3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

React-LINEログインAPIについてまとめてみる

Posted at

ここではユーザー情報を取得するまでの
流れを簡単に説明します。

実際のリクエスト方法はこちら

リクエストに必要なチャネルIDをまだ取得していない人はこちら

プロダクト

LINEログイン

LINEログイン v2.1 APIリファレンス

ログインフロー

そのまま拝借
image.png

1-ユーザーに認証と認可を要求する

METHOD: GET

REQUEST_URL:
https://access.line.me/oauth2/v2.1/authorize
?response_type=code
&client_id={LINEログインチャネルのチャネルID}
&redirect_uri={リダイレクトURL}
&state=12345abcde
&scope=profile%20openid

上記URLをブラウザのアドレスバーに入力すると
おなじみの画面に遷移
image.png
「ログイン」ボタンを押すと任意の画面に遷移。
このときに{リダイレクトURL}にジャンプする。

image.png

リダイレクト先のアドレスのcodeを使用して
アクセストークンを取得する

なお、他パラメータの説明は以下

Reactでログイン認可実装

フローは
Webアプリのログインボタン押下(onClick)

LINEログイン画面表示、「ログイン」押下(認可)

LINEコンソールで指定したリダイレクトURLでパラメータを取得

ログイン処理のコンポーネント
const loginClick = async () => {
    const url = 
`
https://access.line.me/oauth2/v2.1/authorize
?response_type=code
&client_id=${CHANNEL_ID} // チャネルID
&redirect_uri=${REDIRECT_URL} // 「LINEログイン設定」で設定したコールバックURL
&state=12345abcde
&scope=profile%20openid
&nonce=09876xyz
`
    // 生成したURLにジャンプ
    window.location.href = url;
}

公式のログインボタンを押下したら
リダイレクトされるので、
アドレスにくっついてきたパラメータを取得する

リダイレクト先のコンポーネント
React.useEffect(() => {
    lineInfoProcess()
},[]) 

const lineInfoProcess=()=>{
    const searchParams = new URLSearchParams(location.search);
    // アクセストークン生成に必要な「code」をURLから取得
    console.log(searchParams.get('code'))
}

2-アクセストークンを発行する

curl --location 'https://api.line.me/oauth2/v2.1/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=BxQ3jq4nrKeyGzPALrGw' \
--data-urlencode 'client_id=1661245991' \
--data-urlencode 'client_secret=91ffa5302ca707190482f70b47e2be64' \
--data-urlencode 'code_verifier=wJKN8qz5t8SSI9lMFhBB6qwNkQBkuPZoCxzRhwLRUo1' \
--data-urlencode 'redirect_uri=https://raisack.com/'

Reactでアクセストークンを取得する

1にてcodeを取得したのでそれを使用する

リダイレクト先のコンポーネント
React.useEffect(() => {
    lineInfoProcess()
},[]) 

const lineInfoProcess=()=>{
    const searchParams = new URLSearchParams(location.search);
    // アクセストークン生成に必要な「code」をURLから取得
    
// ----------ここから

    PostAccessTokenGet(searchParams.get('code'))
}


const PostAccessTokenGet = async(code: string | null) => {
    try {
        const data = {
            grant_type: 'authorization_code',
            code: code,
            client_id: CHANNEL_ID, // チャネルID
            client_secret: CLIENT_SECRET, // チャネルシークレット
            redirect_uri: REDIRECT_URL, // 「LINEログイン設定」で設定したコールバックURL
        };
        const response = await axios.post(
            'https://api.line.me/oauth2/v2.1/token', 
            data,
            {
                headers: {
                    'content-type': 'application/x-www-form-urlencoded',
                },
            }
        );
        console.log('GET Seccess:', response)
        // responseの中にアクセストークンが含まれているので
        // useContextなどで保管しておく
        
        // トップページにリダイレクトさせる
        window.location.href = 'http://top-page'
    } catch (error) {
        console.error('GET Error:', error);
    }
  };

これによって、ログイン後にリダイレクト先にジャンプし、
そのままアクセストークンを取得することができる。

レスポンス値は以下

{
  "access_token": "bNl4YEFPI/hjFWhTqexp4MuEw5YPs...",
  "expires_in": 2592000,
  "id_token": "eyJhbGciOiJIUzI1NiJ9...",
  "refresh_token": "Aa1FdeggRhTnPNNpxr8p",
  "scope": "profile",
  "token_type": "Bearer"
}

詳しいパラメータの説明は以下

3-ユーザー情報を取得する

アクセストークンをBearerトークンに設定して
GETリクエストを送信する。

curl -v -X GET https://api.line.me/oauth2/v2.1/userinfo \
-H 'Authorization: Bearer {access token}'

Reactでユーザー情報を取得する ※一部Redux使用

リダイレクト先のコンポーネント
'''
前回2で使用したメソッド。
多少変更。メソッド自体をアクセストークンを返すものとする
'''
const PostAccessTokenGet = async(code: string | null) => {
    try {
        const data = {
            grant_type: 'authorization_code',
            code: code,
            client_id: CHANNEL_ID, // チャネルID
            client_secret: CLIENT_SECRET, // チャネルシークレット
            redirect_uri: REDIRECT_URL, // 「LINEログイン設定」で設定したコールバックURL
        };
        const response = await axios.post(
            'https://api.line.me/oauth2/v2.1/token', 
            data,
            {
                headers: {
                    'content-type': 'application/x-www-form-urlencoded',
                },
            }
        );
// ----------ここから

        // これでstatus:OKならアクセストークンを返す    
        return response.data.access_token

    } catch (error) {
        return Error
    }
  };


// LINEユーザー情報を取得するGETメソッド
const getLineUserInfo = async (acs_token: string | null) => {
    try {
        const response = await fetch('https://api.line.me/oauth2/v2.1/userinfo', {
            method: 'GET',
            headers: {
            'Authorization': 'Bearer ' + acs_token,
            },
        });
    
        if (response.ok) {
            const data = await response.json();
            // reduxのstoreにユーザー情報を保存
            // ※ 別途Reduxを使ってstore設定をする必要があります
            // useDispatch, setLineInfoのimport必須
            dispatch(setLineInfo(data))
        } else {
            return Error
        }
    } catch (error) {
        return Error
    }
};

// アクセストークン取得→ユーザー情報を格納する処理
const lineInfoProcess=()=>{
    PostAccessTokenGet(searchParams.get('code'))
    .then((acs_token)=>{
        // ここの処理終了時にReduxにユーザーデータを保存している
        getLineUserInfo(String(acs_token));
    })
}

output例は以下

{
  "sub": "U1234567890abcdef1234567890abcdef",
  "name": "Taro Line",
  "picture": "https://profile.line-scdn.net/0h8pWWElvzZ19qLk3ywQYYCFZraTIdAGEXEhx9ak56MDxDHiUIVEEsPBspMG1EGSEPAk4uP01t0m5G"
}

subは一意なユーザー識別文字列
nameはLINE登録名
pictureはアイコン

これにて無事
LINE認可

アクセストークン取得

ユーザー情報取得
のフローが完成した。

おまけ:Reduxの使用準備

src
├─Components
│  ├─OutPut.tsx
│  └─LoginProcess.tsx
│
└─store
  ├─store.tsx
  └─lineInfoSlice.tsx

チュートリアルのクイックスタートをちょっと変えただけなのでこれが最適かどうかはわからない。。
ただ機能することは機能するので一応置いておきます。。。

store.jsx
import { configureStore } from '@reduxjs/toolkit'
import lineInfoReducer from './lineInfoSlice'

export const store = configureStore({
  reducer: {
    lineUserData: lineInfoReducer,
  },
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch
lineInfoSlice.tsx
import { createSlice } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'

// store.valueの型を指定
export interface LineInfoState {
  value: string
}

// store.valueの初期値を指定
const initialState: LineInfoState = {
  value: "",
}

// https://redux-toolkit.js.org/api/createslice

export const lineInfoSlice = createSlice({
  name: 'lineInfo',
  initialState,
  reducers: {
    setLineInfo: (state, action: PayloadAction<string>) => {
      state.value = action.payload
    },
  },
})

// Action creators are generated for each case reducer function
export const { setLineInfo } = lineInfoSlice.actions

export default lineInfoSlice.reducer

これでstore、reducerの準備は完了。
setLineInfoを使用してstoreに値を格納する

前章のdispatchでstoreに値を格納する
(前章: Reactでユーザー情報を取得する ※一部Redux使用)

LoginProcess.tsx
import { useDispatch } from 'react-redux'
import { setLineInfo } from '../store/lineInfoSlice'

const LoginProcess = () => {

const dispatch = useDispatch();

// LINEユーザー情報を取得するGETメソッド
const getLineUserInfo = async (acs_token: string | null) => {
    ...
    dispatch(setLineInfo(data));
})

return (
    <div> ... </div>
  )
}
export default LoginProcess

次にOutPut.tsxでstoreの値を取得してみる

OutPut.tsx
import { useSelector } from 'react-redux'
import type { RootState } from '../../store/store'

const OutPut = () => {

// store値を定数に格納。
// Rootstateは型
const lineSub = useSelector((state: RootState) => state.lineUserData.value)

return (
    <div>
         {/* クリックするとstore値をポップアップで取得する */}
        <button onClick={()=>{alert(lineSub.sub)}}>
            Push
        </button>
    </div>
  )
}
export default OutPut

0-チャネルID取得方法

下記から今すぐ始めようをクリックし、必要項目を入力
(LINE Developersにログインしておく必要があります)

image.png

プロバイダー
どのアプリで使うか?

チャネル名
LINEプラットフォーム名?

必要項目を記入すると下記画面に飛ぶ
赤枠部分がチャネルID
image.png
※個人情報は伏せてあります

LINEログイン設定でコールバックURLを設定する。
設定しないとURLがうまく機能しない。

image.png

2要素認証の必須化を選択すると、
「ログイン」ボタン押下後に、情報を渡しますか?
などの2段階にわたって確認が求められる。

ここでは2要素認証は適用しない。

「開発中」の場合は自分のLINEアカウントでしか使用できない。
ほかの人のLINEログイン認可をするためには
「開発中」→「公開中」に変更する必要がある

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?