flaskでLINEログインAPIと連携する4つのステップ【初心者向き】

flaskで作ったアプリに、LINEログイン機能を実装してみたい。

今回は、LINEログインをAPIを用いて、flaskに接続するところまでを行います。

アプリ作成時に、外部のAPIとの連携ができると大きく開発の幅が広がりますので、ここでその要素をつかんでいってほしいと思います。

実際に実行して動作確認ができているので、ぜひ一緒に実行して試していただければと思います。

LINEログインAPIとは

LINEログインAPIとは、webアプリなどのログインをLINEの情報を使うようにするシステムとなります。

webアプリなどで、「LINEでログイン」や「Googleアカウントでログイン」「Yahooで....」などをよく見かけるのではないでしょうか。

それらは、webアプリでのログイン機能は使わず、LINEなどにログイン処理を任せ、情報だけもらうようにしている処理を組み込んでいることとなります。

利点としては、

ログイン時のユーザー情報をDBに保存しなくてもよいので、セキュリティ面では安心できます。

このような、LINEを使ったログインは、LINEログインAPIを用いて実装されています。

あべべ

今回は、flaskでLINEログインを実装する方法を解説していきます。

連携するまでに必要なこと

  1. LINE Developersに登録
  2. チャネルIDとチャネルシークレットを取得

LINEログインAPIを使うには、LINE Develpopersツールへの登録が必要になります。

こちらの登録は済ませておいてください。

ログインができると、「チャネル基本設定」が見れるようになります。

その中に、「チャネルID」「チャネルシークレット」が表示されていますので、コピーしておきましょう。

LINEログインAPIの処理の流れと解説順番

LINEログインAPIのコード解説の前に、LINEのログイン処理を行うときの、処理順を整理していこうと思います。

①Access the LINE Login authorization URL with 'redirect_url' and 'state'

LINEログインAPI(LINE Platform)に認証画面を要求します。

※①と②の間で、ユーザーがログインと情報の許可をする

②Access 'redirect_url' with 'state' and authorization code

認可レスポンスを受け取る

③Request access token

認可レスポンスから、アクセストークンを取得する

④Request user profile information

アクセストークンを使用し、ユーザー情報を取得する

この4ステップの順番にコードを見ていきます。

①LINEログインAPI(LINE Platform)に認証画面を要求する

import hashlib
from flask import Flask, request, redirect, session,render_template
import urllib.request
import urllib.parse
import json
import base64
from pprint import pprint
import os

# クライアント情報
# Channel ID
client_id = "<チャネルID>"
# Channel Secret
client_secret = "<チャネルシークレット>"
# Callback URL
redirect_uri = 'http://localhost:5000/callback'

# LINE エンドポイント
authorization_url = 'https://access.line.me/dialog/oauth/weblogin'
token_url = 'https://api.line.me/v2/oauth/accessToken'
user_info_url = 'https://api.line.me/v2/profile'

app = Flask(__name__)
app.secret_key = 'session_key'

# 1.LINEへ認可リクエスト(Authorization Request)を行う。
# ユーザーに認証と認可を要求する:https://developers.line.biz/ja/docs/line-login/integrate-line-login-v2/#making-an-authorization-request
@app.route("/login")
def login():
    # ステート生成
    state = '123456'
    session['state'] = state
    # 認可リクエスト
    return redirect(authorization_url+'?{}'.format(urllib.parse.urlencode({
        'client_id': client_id,
        'redirect_uri': redirect_uri,
        'state': state,
        'response_type': 'code'
    })))

LINEに認可リクエストを送信する処理です。

LINEAPIから、レスポンスを返される(次の処理)ときに、同じユーザーに対してのものか確認できるよう、「state」をsessionに保存しておきます。

※ここでは、簡単な数字にしていますが、実装するとききはランダムな文字列を入れるようにしましょう。

LINEに返すURL(Authorization_url)に、URLパラメーターとして各種変数を渡します。

urllib.parse.urlencodeでパラメーターに変換できます。詳しくは以下の記事で解説しています。

あべべ

redirect_urlには、LINEAPIから、レスポンスを返されるURLを指定します。

ここでは、ローカルで実施なので、「http://localhost:5000/callback」としていますが、リダイレクト先が間違っていないかも確認しておきましょう!!

②認可レスポンスを受け取る

以降②ー④はcallback関数の中の処理になります。

# 認可リクエスト受信 → トークンリクエスト → ユーザープロフィールリクエスト
@app.route("/callback")
def callback():
    # 2. ユーザー認証/同意を行い、認可レスポンスを受け取る。
    # 認可コードを受け取る:https://developers.line.biz/ja/docs/line-login/integrate-line-login-v2/#receiving-the-authorization-code
    state = request.args.get('state')
    if state != session['state']:
        print("invalid_redirect")
    code = request.args.get('code')

ここでは、LINEAPIから受け取ったURLパラメーターを取得します

「state」「code」が渡されますので、それらを取得します。

stateは先ほどお話しした、同じユーザーか確認する値なので、sessionの値と等しいかを確認します。

codeは認可コードです。

③認可レスポンスから、アクセストークンを取得する

    # 3. 認可レスポンスを使ってトークンリクエストを行う。
    # ウェブアプリでアクセストークンを取得する:https://developers.line.biz/ja/docs/line-login/integrate-line-login-v2/#get-access-token
    body = urllib.parse.urlencode({
        'code': code,
        'client_id': client_id,
        'client_secret': client_secret,
        'redirect_uri': redirect_uri,
        'grant_type': 'authorization_code'
    }).encode('utf-8')
    headers = {
        'Content-Type':'application/x-www-form-urlencoded'
    }
    req, res = '', ''
    req = urllib.request.Request(token_url, headers=headers, method='POST')
    with urllib.request.urlopen(req, data=body) as f:
        res = f.read()
    access_token = json.loads(res)['access_token']

ここでは、先ほど受け取った認可コード(code)を用いて、アクセストークンURL(token_url)にアクセスします

アクセストークンを取得するための、要素は公式ドキュメントで指定してありますので、そのまま入れます。

レスポンス(res)には、いくつか変数が返ってきますが、今回はアクセストークン(access_token)のみでよいので、それのみ取得します。

④アクセストークンを使用し、ユーザー情報を取得する

    # 4. 取得したアクセストークンを使用してユーザープロフィールを取得する。
    # ユーザープロフィールを取得する:https://developers.line.biz/ja/docs/line-login/managing-users/#get-profile
    headers = {
        'Authorization': 'Bearer ' + access_token
    }
    req = urllib.request.Request(user_info_url, headers=headers, method='GET')
    with urllib.request.urlopen(req) as f:
        res = f.read()

    return render_template('index.html', test1=json.loads(res)) 

取得したアクセストークンを用いて、ユーザーのプロフィールを取得します

ユーザー情報の取得も、公式ドキュメントに同様に書いてありますので、それを書きます。

ちなみに、今回はheader情報のみになります。

全コード

以下に全コードを載せておきます。

こちらから
import hashlib
from flask import Flask, request, redirect, session,render_template
import urllib.request
import urllib.parse
import json
import base64
from pprint import pprint
import os

# クライアント情報
# Channel ID
client_id = "<チャネルID>"
# Channel Secret
client_secret = "<チャネルシークレット>"
# Callback URL
redirect_uri = 'http://localhost:5000/callback'

# LINE エンドポイント
authorization_url = 'https://access.line.me/dialog/oauth/weblogin'
token_url = 'https://api.line.me/v2/oauth/accessToken'
user_info_url = 'https://api.line.me/v2/profile'

app = Flask(__name__)
app.secret_key = 'session_key'

# 1.LINEへ認可リクエスト(Authorization Request)を行う。
# ユーザーに認証と認可を要求する:https://developers.line.biz/ja/docs/line-login/integrate-line-login-v2/#making-an-authorization-request
@app.route("/login")
def login():
    # ステート生成
    #state = hashlib.sha256(os.urandom(32)).hexdigest()
    state = '123456'
    session['state'] = state
    # 認可リクエスト
    return redirect(authorization_url+'?{}'.format(urllib.parse.urlencode({
        'client_id': client_id,
        'redirect_uri': redirect_uri,
        'state': state,
        'response_type': 'code'
    })))


# 認可リクエスト受信 → トークンリクエスト → ユーザープロフィールリクエスト
@app.route("/callback")
def callback():
    # 2. ユーザー認証/同意を行い、認可レスポンスを受け取る。
    # 認可コードを受け取る:https://developers.line.biz/ja/docs/line-login/integrate-line-login-v2/#receiving-the-authorization-code
    state = request.args.get('state')
    if state != session['state']:
        print("invalid_redirect")
    code = request.args.get('code')

    # 3. 認可レスポンスを使ってトークンリクエストを行う。
    # ウェブアプリでアクセストークンを取得する:https://developers.line.biz/ja/docs/line-login/integrate-line-login-v2/#get-access-token
    body = urllib.parse.urlencode({
        'code': code,
        'client_id': client_id,
        'client_secret': client_secret,
        'redirect_uri': redirect_uri,
        'grant_type': 'authorization_code'
    }).encode('utf-8')
    headers = {
        'Content-Type':'application/x-www-form-urlencoded'
    }
    req, res = '', ''
    req = urllib.request.Request(token_url, headers=headers, method='POST')
    with urllib.request.urlopen(req, data=body) as f:
        res = f.read()
    access_token = json.loads(res)['access_token']
    # 4. 取得したアクセストークンを使用してユーザープロフィールを取得する。
    # ユーザープロフィールを取得する:https://developers.line.biz/ja/docs/line-login/managing-users/#get-profile
    headers = {
        'Authorization': 'Bearer ' + access_token
    }
    req = urllib.request.Request(user_info_url, headers=headers, method='GET')
    with urllib.request.urlopen(req) as f:
        res = f.read()

    return render_template('index.html', test1=json.loads(res)) 



if __name__ == "__main__":
    app.run(debug=True)

まとめ

今回はLINEのログインAPIをpython, flaskで接続してみました。

以下の記事ではAWSのS3への接続を行っています。ぜひそちらも併せて読んでみてください。

(Visited 59 times, 1 visits today)