質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

Q&A

解決済

1回答

4176閲覧

GASでLINEログイン後にOauthエラー(invalid_grant, authorization code expired or incompatible)

HirokazuYokota

総合スコア1

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

OAuth 2.0

OAuth 2.0(Open Authorization 2.0)は、APIを通して保護されたリソース(サードパーティのアプリケーション)へアクセスする為のオープンプロトコルです。

0グッド

0クリップ

投稿2020/10/20 04:04

編集2020/10/20 13:26

前提・実現したいこと

GASでLINEログインを用いたWebアプリを作成しています。
Oauth認証を用いてLINE認証した後のコールバック処理で、下記のエラーが発生しています。
何が問題で本事象が発生しているか、また、解決方法についてご存知の方がいらっしゃいましたらご教示頂けないでしょうか。

発生している問題・エラーメッセージ

Error: Error retrieving token: invalid_grant, authorization code expired or incompatible at Service_.getTokenFromResponse_(Service:541:11) at Service_.fetchToken_(Service:516:15) at Service_.handleCallback(Service:399:20)

該当のソースコード

test.gs

gs

1function doGet() { 2 'use strict'; 3 var service = getService(); 4 if (service.hasAccess()) { 5 createAndSendDocument(service.getAccessToken()); 6 return HtmlService.createHtmlOutput('Success'); 7 } 8 // 承認されていない場合、承認リンクをHTMLページに表示 9 var authorizationUrl = service.getAuthorizationUrl(); 10 var template = '<a href="' + authorizationUrl + '" target="_blank">Authorize</a>'; 11 return HtmlService.createHtmlOutput(template); 12} 13 14/** 15 * OAuth 2.0 serviceのセットアップ 16 */ 17function getService() { 18 'use strict'; 19 // OAuth 2.0承認サービスの生成 20 return OAuth2.createService('line') 21 22 .setAuthorizationBaseUrl('https://access.line.me/dialog/oauth/weblogin')// 認可エンドポイント 23 .setTokenUrl('https://api.line.me/oauth2/v2.1/token')// トークンエンドポイント 24 25 // LINEログインのクライアントIDおよびクライアントシークレットを設定 26 .setClientId('xxxxxxxxxx') // OAuthクライアントID 27 .setClientSecret('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx') // OAuthクライアントシークレット 28 29 // OAuth2.0 承認後のコールバック関数名の設定 30 .setCallbackFunction('authCallback') 31 // 承認トークンを維持するプロパティーストアの設定 32 .setPropertyStore(PropertiesService.getUserProperties()) 33 // LINEログインリクエストのスコープ設定 34 .setScope('profile'); // LINEログインのスコープ 35} 36 37/** 38 * 最初のOAuth2承認の際のコールバック処理 39 */ 40function authCallback(request) { 41 'use strict'; 42 var service = getService(); 43 var authorized = service.handleCallback(request); 44 if (authorized) { 45 createAndSendDocument(service.getAccessToken()); 46 return HtmlService.createHtmlOutput('Success!'); 47 } 48 return HtmlService.createHtmlOutput('Denied.'); 49}

Oauthライブラリのソース抜粋
ソースコード全文

js

1Service_.prototype.handleCallback = function(callbackRequest) { 2 var code = callbackRequest.parameter.code; 3 var error = callbackRequest.parameter.error; 4 if (error) { 5 if (error == 'access_denied') { 6 return false; 7 } else { 8 throw new Error('Error authorizing token: ' + error); 9 } 10 } 11 validate_({ 12 'Client ID': this.clientId_, 13 'Client Secret': this.clientSecret_, 14 'Token URL': this.tokenUrl_ 15 }); 16 var payload = { 17 code: code, 18 client_id: this.clientId_, 19 client_secret: this.clientSecret_, 20 redirect_uri: this.getRedirectUri(), 21 grant_type: 'authorization_code' 22 }; 23 var token = this.fetchToken_(payload); 24 this.saveToken_(token); 25 return true; 26}; 27 28/** 29 * Fetches a new token from the OAuth server. 30 * @param {Object} payload The token request payload. 31 * @param {string} [optUrl] The URL of the token endpoint. 32 * @return {Object} The parsed token. 33 */ 34Service_.prototype.fetchToken_ = function(payload, optUrl) { 35 // Use the configured token URL unless one is specified. 36 var url = optUrl || this.tokenUrl_; 37 var headers = { 38 'Accept': this.tokenFormat_ 39 }; 40 if (this.tokenHeaders_) { 41 headers = extend_(headers, this.tokenHeaders_); 42 } 43 if (this.tokenPayloadHandler_) { 44 payload = this.tokenPayloadHandler_(payload); 45 } 46 var response = UrlFetchApp.fetch(url, { 47 method: 'post', 48 headers: headers, 49 payload: payload, 50 muteHttpExceptions: true 51 }); 52 return this.getTokenFromResponse_(response); 53}; 54 55/** 56 * Gets the token from a UrlFetchApp response. 57 * @param {UrlFetchApp.HTTPResponse} response The response object. 58 * @return {!Object} The parsed token. 59 * @throws If the token cannot be parsed or the response contained an error. 60 * @private 61 */ 62Service_.prototype.getTokenFromResponse_ = function(response) { 63 var token = this.parseToken_(response.getContentText()); 64 var resCode = response.getResponseCode(); 65 if ( resCode < 200 || resCode >= 300 || token.error) { 66 var reason = [ 67 token.error, 68 token.message, 69 token.error_description, 70 token.error_uri 71 ].filter(Boolean).map(function(part) { 72 return typeof(part) == 'string' ? part : JSON.stringify(part); 73 }).join(', '); 74 if (!reason) { 75 reason = resCode + ': ' + JSON.stringify(token); 76 } 77 throw new Error('Error retrieving token: ' + reason); 78 } 79 return token; 80};

試したこと

コールバック処理(authCallback)のINPUTパラメータ(request)の中身をログに出力したものの何が問題かが十分に分かりません。

log

1{ 2 parameters={ 3 code=[uLuj9s4Asa1qujrtAGm0] 4 , serviceName=line 5 , state=[ADEpC8zLJCo5fkyokPfDcyVfYbFS-2fdPU0DUBfrJOmN9E5-OWKdZW012RW3JViXtPw9EXtztv2FkxNqpeJ_3gkyhHb0xm-KDobrNbMz2NB_lV9scjSXFfdlnkD_FvCXNKR30oDMM1qOIBgxpwEFDLxq9mTVh0_sr2ZGNApQKsUpAa1y5PVrW70] 6 } 7 , parameter={ 8 serviceName=line 9 , code=uLuj9s4Asa1qujrtAGm0 10 , state=ADEpC8zLJCo5fkyokPfDcyVfYbFS-2fdPU0DUBfrJOmN9E5-OWKdZW012RW3JViXtPw9EXtztv2FkxNqpeJ_3gkyhHb0xm-KDobrNbMz2NB_lV9scjSXFfdlnkD_FvCXNKR30oDMM1qOIBgxpwEFDLxq9mTVh0_sr2ZGNApQKsUpAa1y5PVrW70 11 } 12 , queryString=code=uLuj9s4Asa1qujrtAGm0 13 &state=ADEpC8zLJCo5fkyokPfDcyVfYbFS-2fdPU0DUBfrJOmN9E5-OWKdZW012RW3JViXtPw9EXtztv2FkxNqpeJ_3gkyhHb0xm-KDobrNbMz2NB_lV9scjSXFfdlnkD_FvCXNKR30oDMM1qOIBgxpwEFDLxq9mTVh0_sr2ZGNApQKsUpAa1y5PVrW70 14 , contextPath= 15 , contentLength=-1.0 16}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

エラー原因

エラーの原因はトークンエンドポイントの指定誤り。
誤)https://api.line.me/oauth2/v2.1/token
正)https://api.line.me/v2/oauth/accessToken
参考にしたサイト
※上記の参考サイト内ではv1との記載があったが、v1試してみたところ現在は非推奨であるとのエラーとなったため、v2で試したところHTTPステータス200で返却された。

###試したこと
Oauth2のライブラリをGITからDLして自プロジェクト内にデプロイし、ログを埋め込んで検証を行った。
上記の参考サイトの内容を基に、トークンエンドポイントのURLに誤りがあることを検知した。

投稿2020/10/20 13:24

HirokazuYokota

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問