LaravelとLineをつないで、LINEアカウントでログインさせたり、Laravel側からLINEにメッセージを送信したりできます。
LINE連携で、色々とできることが広がっていきますよね。
今回はログイン用の設定を行っていきます。バージョンLaravel8を使いました。
LINE側の設定
LINE側の設定をすすめていきましょう。
LINE Developpersを使って色々設定していきますが、最初は既存のLINEアカウントまたはビジネスアカウントでログインを求められます。どちらかでログインをします。
とりあえずテストしてみるなら、既存のLINEアカウントを使ったほうがラクかと思います。
その先の設定は、次のとおりです。
LINEログイン用チャンネルを作成
LINE DeveloppersのページからLINEログインを選択。
【今すぐはじめよう】ボタンをクリックして、登録スタート。
下記に入力して、開発者契約同意にチェックを入れ、【作成】ボタンをクリックします。
- プロバイダー:新規プロバイダー作成
- プロバイダー名:お好きなもの
- チャンネルアイコン:お好きなもの
- チャンネル名:お好きなもの
- チャンネル説明:お好きなもの
- アプリタイプ:ウェブアプリ
- メールアドレス
公開済みか非公開か選択する画面が出てきます。テスト用なら非公開で良いかと思いますが、機能によっては、うまく試せないこともあるようです。
わたしは公開用で作っちゃったので良く分かりませんが。
なおLINEのマニュアルには、次のように書かれています。
LINEログインのチャネルは「非公開」のステータスで作成されます。チャネルが非公開の場合は、AdminまたはTesterの権限(詳しくは、「権限を管理する」を参照)を持つユーザーのみがLINEログインを利用できます。そのほかのユーザーもLINEログインを利用できるようにするには、ステータスを「公開済み」に変更してください。
Lineマニュアル:https://developers.line.biz/ja/docs/line-login/getting-started/#step-4-customize-your-app
とりあえず非公開にして、後から必要に応じて公開にすると良いかと思います。ちなみに公開を選択したら、後から非公開に戻すはできません。
チャンネルIDとチャンネルシークレット取得
チャンネル作成後は、チャンネルIDとチャンネルシークレットを取得しておきましょう。
LaravelとLINEを連携させるために、この2つが必要となります。
作成後のページの上に「チャンネルID」、下のほうに「チャンネルシークレット」があります。こちら、それぞれコピーしておきます。
【チャンネルID】
【チャンネルシークレット】
なおこの下に、OpenID Connectがあります。
ユーザーのメールアドレスを取得する場合は、何に使うのかといった目的をユーザーに伝える必要があります。この画面をスクリーンショットで取って、LINE側に申請せねばなりません。
メールアドレス取得をしたい場合は、こちらも行っておきましょう。
具体的には【申請】ボタンを押し、チェックボックスにチェックをいれた後、スクリーンショットを添付して送るだけです。
わたしは、次のような文章を送りました。LINE以外のログインもつけるかもしれないので、他のSNSについても言及しております。
申請後、すぐに次の画面になりました。
コールバックURI指定
さらに隣の「LINEログイン設定」タブにうつり、コールバックURLを設定します。
こちらはまだ未設定ですが、次のようにいれておきます。
【https://{ドメイン}/callback】
ドメインはご利用のものを入れてください。
なお、まだURLを準備していない場合には、NGROKを使って、https://で始まるテスト用URLを簡単に作成できます。詳しくはこちらの記事をご覧ください。
Laravel側の設定
上記までがLineの設定ですが、次にLaravelにうつります。
Laravelプロジェクトを準備
とりあえず前準備としては、プロジェクトの作成・ログイン機能の実装を行っておきます。すでにプロジェクトが準備できている場合は、ここは飛ばしてください。
まず次のコマンドを入力してプロジェクトを作ります。
【プロジェクト作成】
1 |
composer create-project --prefer-dist laravel/laravel linelogin |
Bootstrapでログイン機能もつけておきます。
【ログイン機能(Bootstrap)実装】
1 |
composer require laravel/ui |
1 |
php artisan ui bootstrap --auth |
npm install と npm run dev を実行します。
さらにProviders/RouteServiceProvider.phpの29行目のコメントアウトを外し、有効化しておきます。
【RouteServiceProvider.php】
1 |
protected $namespace = 'App\\Http\\Controllers'; |
これでOKです。
ざっくり書きましたが、Laravelの詳しいインストール手順を知りたい方はこちらをご覧ください。
LaravelとLine連携準備
プロジェクト作成後、プロジェクト内の.envファイルを開きます。
Line側で設定してきた 「チャンネルID」「チャンネルシークレット」【https://{ドメイン}/line/callback】を入れておきます。
【.env】
1 2 3 |
LINE_CHANNEL_ID=チャンネルID LINE_CHANNEL_SECRET=チャンネルシークレット LINE_REDIRECT=https://{ドメイン}/callback |
次にconfigにも、この設定を反映します。config/servicesの中に下記コードを追加します。
【services.php】
1 2 3 4 5 |
'line' => [ 'client_id'=>env('LINE_CHANNEL_ID'), 'client_secret' =>env('LINE_CHANNEL_SECRET'), 'redirect'=>env('LINE_REDIRECT'), ], |
ここまでで、連携準備完了です!
Laravelのユーザーテーブルの準備
database/migrationsの中の一番上の【create_users_table.php】を開きます。
デフォルトのusersテーブルをアレンジして、次のようにしておきます。
【usersテーブル用のマイグレーションファイル】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique()->nullable(); $table->timestamp('email_verified_at')->nullable(); $table->string('password')->nullable(); $table->string('provider')->nullable(); $table->string('line_id')->nullable(); $table->rememberToken(); $table->timestamps(); }); } |
このあたりは運用によって異なる部分ですが、とりあえず今回は、メールアドレスやパスワードはnullable設定にし、さらにSNSログイン用にprovider, line_idといったカラムを加えておきます。
保存後、マイグレートを実行します。
1 |
php artisan migrate |
Lineログイン用コントローラの作成
次にLineログイン用のコントローラを作成します。
こちらのTakaさんの記事を参考にさせて頂きました。
いろんな記事がありましたが、こちらが一番シンプルで、使いやすそうでした。
まずはコントローラを作成します。
1 |
php artisan make:controller LineLoginController |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Str; use App\Models\User; use Illuminate\Support\Facades\Auth; class LineLoginController extends Controller { // Lineログイン画面を表示 public function lineLogin() { $state = Str::random(32); $nonce = Str::random(32); $uri ="https://access.line.me/oauth2/v2.1/authorize?"; $response_type = "response_type=code"; $client_id = "&client_id=".config('services.line.client_id'); $redirect_uri ="&redirect_uri=".config('services.line.redirect'); $state_uri = "&state=".$state; $scope = "&scope=openid%20profile"; $prompt = "&prompt=consent"; $nonce_uri = "&nonce="; $uri = $uri . $response_type . $client_id . $redirect_uri . $state_uri . $scope . $prompt . $nonce_uri; return redirect($uri); } // アクセストークン取得 public function getAccessToken($req) { $headers = [ 'Content-Type: application/x-www-form-urlencoded' ]; $post_data = array( 'grant_type' => 'authorization_code', 'code' => $req['code'], 'redirect_uri' => config('services.line.redirect'), 'client_id' => config('services.line.client_id'), 'client_secret' => config('services.line.client_secret'), ); $url = 'https://api.line.me/oauth2/v2.1/token'; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post_data)); $res = curl_exec($curl); curl_close($curl); $json = json_decode($res); $accessToken = $json->access_token; return $accessToken; } // プロフィール取得 public function getProfile($at) { $curl = curl_init(); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $at)); curl_setopt($curl, CURLOPT_URL, 'https://api.line.me/v2/profile'); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET'); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $res = curl_exec($curl); curl_close($curl); $json = json_decode($res); return $json; } // ログイン後のページ表示 public function callback(Request $request) { $accessToken = $this->getAccessToken($request); $profile = $this->getProfile($accessToken); // ユーザー情報あるか確認 $user=User::where('line_id', $profile->userId)->first(); // あったらログイン if($user) { Auth::login($user); return redirect('/home'); // なければ登録してからログイン }else { $user=new User(); $user->provider='line'; $user->line_id=$profile->userId; $user->name=$profile->displayName; $user->save(); Auth::login($user); return redirect('/home'); } } } |
Lineログイン用ルート設定
ルート設定は、こちら。最初からあるルート設定は残しておき、最後に2つ追加します。
【web.php】
1 2 3 4 5 6 7 8 9 10 11 |
Auth::routes(); Route::get('/', function () { return view('welcome'); }); Route::get('/home', 'HomeController@index')->name('home'); // 2行追加 Route::get('/linelogin', 'LineLoginController@lineLogin')->name('linelogin'); Route::get('/callback', 'LineLoginController@callback')->name('callback'); |
これによって、次の通り処理が進みます。
- welcomeページにLINEログインへのリンク作成
- LINEログインへのリンクをクリックすると、’linelogin’ルートによりLINEログインページ掲載
- ログイン後は、’callback’ルートの処理が実行され、’home’画面が表示
LINEログイン用ビューファイル
まずはログインページへのリンクをつけます。
本当はLINEの規約に従ってボタンを作らねばいけません。詳細ガイドはこちら。
今回はテストなので、適当なリンクにしておきます。
resources/view/welcome.blade.phpファイルの34行目あたりに、リンクを追加します。
【welcome.blade.php】
1 |
<a href="{{route('linelogin')}}">LINEログイン</a> |
これでOKです。テストしてみましょう♪
テストしてみる
ブラウザを表示すると、LINEログインが右上あたりに表示されます。
こちらをクリックすると、ログイン画面へ。
さらにポチると、こんな画面へ。許可するボタンをクリック。
そしてそのあとは、home画面が表示されます。デフォルトのままなので、こんなですが。
というわけで、LINEログインできました。
access_tokenエラーになった場合
実はわたしは、最初は許可するボタンクリック後、下記のエラーメッセージが出て、access_tokenで何度かエラーになりました。
ddを使ってみると値が取れているはずなのに、おかしな現象です。
エラー解決のためググってみると、teratailにて、同じようなエラーにあった人がいました。その人はWindows環境でなければうまくいったそうです。
わたしの場合はWindows環境でテストしておりますが、そのまま、ddを使ったりして色々と試すうち、そのままのコードでうまくいきました。
釈然としない説明で申し訳ないですが、もし参考になればと思い、掲載しておきます。
さいごに
今回はざっくりですが、実際にはLINEログインページへのボタンを作らねばなりません。
またデータベースも、運用によって作り変える必要がでてきます。たとえばユーザーテーブルとは別に、SNS用テーブルを作る手もあります。
このあたりは用途によって、変えていってくださいね。
とりあえず、今回はここまでにします。
楽しくなってきたので、今度はチャットボットとか
試してみたいなと思います。