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プロジェクトを準備
とりあえず前準備としては、プロジェクトの作成・ログイン機能の実装を行っておきます。すでにプロジェクトが準備できている場合は、ここは飛ばしてください。
まず次のコマンドを入力してプロジェクトを作ります。
【プロジェクト作成】
composer create-project --prefer-dist laravel/laravel linelogin
Bootstrapでログイン機能もつけておきます。
【ログイン機能(Bootstrap)実装】
composer require laravel/ui
php artisan ui bootstrap --auth
npm install と npm run dev を実行します。
さらにProviders/RouteServiceProvider.phpの29行目のコメントアウトを外し、有効化しておきます。
【RouteServiceProvider.php】
protected $namespace = 'App\\Http\\Controllers';
これでOKです。
ざっくり書きましたが、Laravelの詳しいインストール手順を知りたい方はこちらをご覧ください。
LaravelとLine連携準備
プロジェクト作成後、プロジェクト内の.envファイルを開きます。
Line側で設定してきた 「チャンネルID」「チャンネルシークレット」【https://{ドメイン}/line/callback】を入れておきます。
【.env】
LINE_CHANNEL_ID=チャンネルID
LINE_CHANNEL_SECRET=チャンネルシークレット
LINE_REDIRECT=https://{ドメイン}/callback
次にconfigにも、この設定を反映します。config/servicesの中に下記コードを追加します。
【services.php】
'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テーブル用のマイグレーションファイル】
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といったカラムを加えておきます。
保存後、マイグレートを実行します。
php artisan migrate
Lineログイン用コントローラの作成
次にLineログイン用のコントローラを作成します。
こちらのTakaさんの記事を参考にさせて頂きました。

いろんな記事がありましたが、こちらが一番シンプルで、使いやすそうでした。
まずはコントローラを作成します。
php artisan make:controller LineLoginController
<?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】
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】
<a href="{{route('linelogin')}}">LINEログイン</a>
これでOKです。テストしてみましょう♪
テストしてみる
ブラウザを表示すると、LINEログインが右上あたりに表示されます。

こちらをクリックすると、ログイン画面へ。

さらにポチると、こんな画面へ。許可するボタンをクリック。

そしてそのあとは、home画面が表示されます。デフォルトのままなので、こんなですが。

というわけで、LINEログインできました。
access_tokenエラーになった場合
実はわたしは、最初は許可するボタンクリック後、下記のエラーメッセージが出て、access_tokenで何度かエラーになりました。
ddを使ってみると値が取れているはずなのに、おかしな現象です。
エラー解決のためググってみると、teratailにて、同じようなエラーにあった人がいました。その人はWindows環境でなければうまくいったそうです。
わたしの場合はWindows環境でテストしておりますが、そのまま、ddを使ったりして色々と試すうち、そのままのコードでうまくいきました。
釈然としない説明で申し訳ないですが、もし参考になればと思い、掲載しておきます。
さいごに
今回はざっくりですが、実際にはLINEログインページへのボタンを作らねばなりません。
またデータベースも、運用によって作り変える必要がでてきます。たとえばユーザーテーブルとは別に、SNS用テーブルを作る手もあります。
このあたりは用途によって、変えていってくださいね。
とりあえず、今回はここまでにします。

楽しくなってきたので、今度はチャットボットとか
試してみたいなと思います。





コメント