利用 Laravel 實作 Line 登入,並取得使用者的 ID 及 資料
利用 Laravel 實作 Line login 取得使用者資料
教學開始,為何要寫這篇?因為剛好專案需要,需要取得使用者在某個 provider 之下的 ID,就順便寫這篇了,如果是剛好要實作 Line Login 的朋友可以直接參考。
首先,先到
註冊一個 Line Login 的 Service,如果連這個都要教學,那我也沒辦法了。(其實只是懶得截圖?),註冊完成後可以在 Channel Setting 內取得
- Channel ID
- Channel Secret
這兩個需要記下來~
另外在 App Setting 中有個 Callback Url,之後也要填寫,下方會教你該填寫什麼,這個欄位是 Line 拿來驗證與最後回呼你的網址。
以下準備好之後,首先把我們的 Laravel 專案建立起來
基本上我都是使用 Laravel 5.5 的 LTS 版本。
composer create-project --prefer-dist laravel/laravel login-demo "5.5.*"
不知道 composer 是什麼的可以去官網下載安裝
專案建立起來之後就可以按照步驟來:
第一步:編輯我們的 .env 檔案
APP_URL
改成你的網址- 新增兩個欄位
LINE_CHANNEL_ID=這邊填寫你的 Channel ID
LINE_SECRET=這邊填寫你的 Channel Secret
第二步:來在 config
資料夾底下新增一個 line.php
,內容如下
<?php
return [
'channel_id' => env('LINE_CHANNEL_ID'),
'secret' => env('LINE_SECRET'),
'authorize_base_url' => 'https://access.line.me/oauth2/v2.1/authorize',
'get_token_url' => 'https://api.line.me/oauth2/v2.1/token',
'get_user_profile_url' => 'https://api.line.me/v2/profile',
];
主要是記錄一些 Line API 的位址,跟把 env 資料讀進來。
第三步:安裝 Guzzle 套件
主要是拿來取代 Curl 用的。
composer require guzzlehttp/guzzle:~6.0
第四步:建立程式碼
- 建立路由
打開我們的 routes/web.php
貼上以下路由程式碼
Route::get('/line', 'LoginController@pageLine');
Route::get('/callback/login', 'LoginController@lineLoginCallBack');
2. 建立 View
在 resources/views
底下建立一個 line.blade.php
貼上以下 blade 程式碼
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Line Login Demo</title>
<!-- Bootstrap core CSS -->
<link href="https://bootstrap.hexschool.com/docs/4.2/dist/css/bootstrap.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="https://bootstrap.hexschool.com/docs/4.2/examples/floating-labels/floating-labels.css" rel="stylesheet">
</head>
<body>
<form class="form-signin">
<div class="text-center mb-4">
<a href="{{ $url }}"><img class="mb-4" src="/images/line/2x/32dp/btn_login_base.png"></a>
</div>
<p class="mt-5 mb-3 text-muted text-center">Yulin © 2019</p>
</form>
</body>
</html>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
注意其中的
/images/line/2x/32dp/btn_login_base.png
這邊需要改成你自己的圖片網址,需要登入圖片的可以到 Line 官方下載
3. 創建一個 Controller ,可依照下面指令
php artisan make:controller LoginController
並貼上以下程式碼
<?php
namespace App\Http\Controllers;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Services\LineService;
class LoginController extends Controller
{
protected $lineService;
public function __construct(LineService $lineService)
{
$this->lineService = $lineService;
}
public function pageLine()
{
$url = $this->lineService->getLoginBaseUrl();
return view('line')->with('url', $url);
}
public function lineLoginCallBack(Request $request)
{
try {
$error = $request->input('error', false);
if ($error) {
throw new Exception($request->all());
}
$code = $request->input('code', '');
$response = $this->lineService->getLineToken($code);
$user_profile = $this->lineService->getUserProfile($response['access_token']);
echo "<pre>"; print_r($user_profile); echo "</pre>";
} catch (Exception $ex) {
Log::error($ex);
}
}
}
pageline
只是取得 Line 要求的參數組成網址,並且傳到 view
lineLoginCallBack
則是登入成功後 Line 會呼叫這隻,所以必須把這支網址寫入 App Setting 裡面的 Callback url,上方有提到,內容主要是先跟 Line 取得權杖,隨後 Call Line 取得使用者的 API (透過權杖),實作部分寫在 LineService 裡面
4. 在 app 資料夾底下建立一個 Services 資料夾
5. 在 Services 資料夾底下建立一個 LineService.php
,並貼上下方程式碼
<?php
namespace App\Services;
use GuzzleHttp\Client;
class LineService
{
public function getLoginBaseUrl()
{
// 組成 Line Login Url
$url = config('line.authorize_base_url') . '?';
$url .= 'response_type=code';
$url .= '&client_id=' . config('line.channel_id');
$url .= '&redirect_uri=' . config('app.url') . '/callback/login';
$url .= '&state=test'; // 暫時固定方便測試
$url .= '&scope=openid%20profile';
return $url;
}
public function getLineToken($code)
{
$client = new Client();
$response = $client->request('POST', config('line.get_token_url'), [
'form_params' => [
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => config('app.url') . '/callback/login',
'client_id' => config('line.channel_id'),
'client_secret' => config('line.secret')
]
]);
return json_decode($response->getBody()->getContents(), true);
}
public function getUserProfile($token)
{
$client = new Client();
$headers = [
'Authorization' => 'Bearer ' . $token,
'Accept' => 'application/json',
];
$response = $client->request('GET', config('line.get_user_profile_url'), [
'headers' => $headers
]);
return json_decode($response->getBody()->getContents(), true);
}
}
這邊三隻 function 一一解釋:
getLoginBaseUrl
只是取得 Line 要求的固定網址及參數
getLineToken
則是像 Line 取得我們的權杖 (透過 Channel ID, Channel Secret),這邊也會一併驗證你的 Callback Url 是否相同。
getUserProfile
則是透過 getLineToken
獲得的權杖,去要求存取使用者的資料。
完成後把你的 callback url 也就是 http://yourdomain.xxx/callback/login
貼到上述所說的 callback url 部分。讓 Line 可以驗證並回呼
最後,來到 http://yourdomain.xxx/line
點下圖示最後登入成功後就會出現 Line 回傳給你的使用者資料!
長得會如下方
Array
(
[userId] => 使用者的 ID
[displayName] => 使用者的暱稱
[pictureUrl] => 使用者的大頭貼照網址
)
完整的範例程式碼在 Github 上可以找到
以上如果有問題歡迎提問。