ここではユーザー情報を取得するまでの
流れを簡単に説明します。
実際のリクエスト方法はこちら
リクエストに必要なチャネルIDをまだ取得していない人はこちら
プロダクト
LINEログイン
LINEログイン v2.1 APIリファレンス
ログインフロー
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をブラウザのアドレスバーに入力すると
おなじみの画面に遷移
「ログイン」ボタンを押すと任意の画面に遷移。
このときに{リダイレクトURL}
にジャンプする。
リダイレクト先のアドレスの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
チュートリアルのクイックスタートをちょっと変えただけなのでこれが最適かどうかはわからない。。
ただ機能することは機能するので一応置いておきます。。。
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
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使用)
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の値を取得してみる
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にログインしておく必要があります)
プロバイダー
どのアプリで使うか?
チャネル名
LINEプラットフォーム名?
必要項目を記入すると下記画面に飛ぶ
赤枠部分がチャネルID
※個人情報は伏せてあります
LINEログイン設定でコールバックURLを設定する。
設定しないとURLがうまく機能しない。
2要素認証の必須化
を選択すると、
「ログイン」ボタン押下後に、情報を渡しますか?
などの2段階にわたって確認が求められる。
ここでは2要素認証は適用しない。
「開発中」の場合は自分のLINEアカウントでしか使用できない。
ほかの人のLINEログイン認可をするためには
「開発中」→「公開中」に変更する必要がある