電話番号 電話番号 お問い合わせ

受付時間 平日10:00~18:00

TOP

資料ダウンロードはこちら >>

ロゴ

AWSやシステム・アプリ開発の最新情報|クロスパワーブログ

Lambda(Node.js)でLINEログインのアクセストークンを更新する

Lambda(Node.js)でLINEログインのアクセストークンを更新する

LINEログインで認証が完了するとアクセストークンが得られます。

そのアクセストークンを使用してユーザープロフィールを取得したりユーザーIDを取得したりするわけですが、

アクセストークンは有効期間30日という制限があります。

基本的には31日目からは再ログインしてもらうことになるのですが、

40日目までなら再ログインしなくても新しいアクセストークンを得られます。

 

今回はその新しいアクセストークンを取得する方法をお伝えします。

 

まずはおさらい

 

LINEログインを行い、アクセストークン、リフレッシュトークン、ユーザープロフィールを表示する画面を作ってみましょう。

前回使用したLambda関数を次のように修正してください。

 


var request = require('request');

exports.handler = async(event) => {
    var access_token;
    var refresh_token;
    //LINE認証ページからはcodeが来るので、LINEの認証APIでトークンを取得
    if (event.queryStringParameters.code) {
        var token = await postRequest(
            'https://api.line.me/oauth2/v2.1/token', {
                'grant_type': 'authorization_code',
                'code': event.queryStringParameters.code,
                'redirect_uri': '<API GatewayのURL>',
                'client_id': '<Channel ID>',
                'client_secret': '<Channel Secret>'
            }
        );
        var tokenBody = JSON.parse(token.httpResponse.body);
        access_token = tokenBody.access_token;
        refresh_token = tokenBody.refresh_token;
    }

    //ユーザープロフィール取得
    var profile = await getRequest(
        'https://api.line.me/v2/profile', {
            'auth': {
                'bearer': access_token
            }
        }
    );
    var profileBody = JSON.parse(profile.httpResponse.body);
    const response = {
        statusCode: 200,
        headers: { 'content-type': 'text/html; charset=utf-8' },
        body: `<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>Login</title>
	</head>
	<body>
		<h3>access_token</h3>
		<p>${access_token}</p>
		<h3>refresh_token</h3>
		<p>${refresh_token}</p>
		<h3>pictureUrl</h3>
		<img src="${profileBody.pictureUrl}" style="width:100px"/>
	</body>
</html>
`
    };
    return response;
};

var postRequest = (url, form) => {
    return new Promise((resolve) => {
        request.post({ url: url, form: form },
            (err, httpResponse, body) => {
                resolve({
                    err: err,
                    httpResponse: httpResponse,
                    body: body
                });
            }
        );
    });
};

var getRequest = (url, header) => {
    return new Promise((resolve) => {
        request.get(
            url,
            header,
            (err, httpResponse, body) => {
                resolve({
                    err: err,
                    httpResponse: httpResponse,
                    body: body
                });
            }
        );
    });
};

 

LINEログイン後、画面に”acceess_token”、”refresh_token”とユーザープロフィールのアイコンを表示しています。

 

 

トークンを更新する

 

トークンを更新する時は”refresh_token”を使用します。

 

Lambda関数を次のように変更してください。

 


var request = require('request');

exports.handler = async(event) => {
    var access_token;
    var refresh_token;
    //LINE認証ページからはcodeが来るので、LINEの認証APIでトークンを取得
    if (event.queryStringParameters.code) {
        var token = await postRequest(
            'https://api.line.me/oauth2/v2.1/token', {
                'grant_type': 'authorization_code',
                'code': event.queryStringParameters.code,
                'redirect_uri': '<API GatewayのURL>',
                'client_id': '<Channel ID>',
                'client_secret': '<Channel Secret>'
            }
        );
        var tokenBody = JSON.parse(token.httpResponse.body);
        access_token = tokenBody.access_token;
        refresh_token = tokenBody.refresh_token;
    }

    //リフレッシュの時はリフレッシュトークンを使ってアクセストークン更新
    if (event.queryStringParameters.access_token) {
        var verify = await getRequest(
            'https://api.line.me/oauth2/v2.1/verify?access_token=' + event.queryStringParameters.access_token
        );
        var verifyBody = JSON.parse(verify.httpResponse.body);
        if (verifyBody.scope) {
            var token = await postRequest(
                'https://api.line.me/oauth2/v2.1/token', {
                    'grant_type': 'refresh_token',
                    'refresh_token': event.queryStringParameters.refresh_token,
                    'client_id': '<Channel ID>',
                    'client_secret': '<Channel Secret>'
                }
            );
            var tokenBody = JSON.parse(token.httpResponse.body);
            access_token = tokenBody.access_token;
            refresh_token = tokenBody.refresh_token;
        }
    }

    //ユーザープロフィール取得
    var profile = await getRequest(
        'https://api.line.me/v2/profile', {
            'auth': {
                'bearer': access_token
            }
        }
    );
    var profileBody = JSON.parse(profile.httpResponse.body);
    const response = {
        statusCode: 200,
        headers: { 'content-type': 'text/html; charset=utf-8' },
        body: `<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>Login</title>
	</head>
	<body>
		<h3>access_token</h3>
		<p>${access_token}</p>
		<h3>refresh_token</h3>
		<p>${refresh_token}</p>
		<h3>pictureUrl</h3>
		<img src="${profileBody.pictureUrl}" style="width:100px"/>
		<a href="<API GatewayのURL>?access_token=${access_token}&refresh_token=${refresh_token}">リフレッシュ</a>
	</body>
</html>
`
    };
    return response;
};

var postRequest = (url, form) => {
    return new Promise((resolve) => {
        request.post({ url: url, form: form },
            (err, httpResponse, body) => {
                resolve({
                    err: err,
                    httpResponse: httpResponse,
                    body: body
                });
            }
        );
    });
};

var getRequest = (url, header) => {
    return new Promise((resolve) => {
        request.get(
            url,
            header,
            (err, httpResponse, body) => {
                resolve({
                    err: err,
                    httpResponse: httpResponse,
                    body: body
                });
            }
        );
    });
};

 

先ほどのコードから変更したのは2ヶ所。

 

トークンをリフレッシュするためのリンクを追加。

URLパラメータで”access_token”と”refresh_token”を渡しています。

 


<a href="<API GatewayのURL>?access_token=${access_token}&refresh_token=${refresh_token}">リフレッシュ</a>

 

アクセストークンを更新する処理

 


//リフレッシュの時はリフレッシュトークンを使ってアクセストークン更新
if (event.queryStringParameters.access_token) {
    var verify = await getRequest(
        'https://api.line.me/oauth2/v2.1/verify?access_token=' + event.queryStringParameters.access_token
    );
    var verifyBody = JSON.parse(verify.httpResponse.body);
    if (verifyBody.scope) {
        var token = await postRequest(
            'https://api.line.me/oauth2/v2.1/token', {
                'grant_type': 'refresh_token',
                'refresh_token': event.queryStringParameters.refresh_token,
                'client_id': '<Channel ID>',
                'client_secret': '<Channel Secret>'
            }
        );
        var tokenBody = JSON.parse(token.httpResponse.body);
        access_token = tokenBody.access_token;
        refresh_token = tokenBody.refresh_token;
    }
}

 

まずはLINEトークン確認API”https://api.line.me/oauth2/v2.1/verify”にアクセストークンを渡して

このアクセストークンが本当に使える物なのかをチェックしています。

トークン発行から41日以上経った場合は、レスポンスにエラーメッセージが返ってきます。

 

続いてLINE認証API”https://api.line.me/oauth2/v2.1/token”に新しいアクセストークンを要求します。

URLを見れば分かりますが、これは最初に”code”から”access_token”を作ったAPIと同じ物になります。

「’grant_type’: ‘authorization_code’」を指定するとトークン更新モードになるようです。

 

実際の動きは次のようになります。

 

 

リフレッシュを押すごとに”access_token”が更新されていきくのが分かります。

 

なお、LINEログインを最初に行なった場合はスマホのLINEに通知が飛びますが

トークンを更新した場合は通知は飛ばないようです。

なので常識の範囲でバックグラウンドでトークンの更新を行う分には、ユーザーに迷惑をかけずに取り入れることができると思います。