Thank
https://medium.com/laravel-news/adding-auth-providers-to-laravel-socialite-ca0335929e42 This have problems https://socialiteproviders.com/Line/1.
composer require socialiteproviders/line
2. create app/Providers/LineProvider.php
https://github.com/SocialiteProviders/Line/blob/master/Provider.php
namespace App\Providers;
use GuzzleHttp\RequestOptions;
use Laravel\Socialite\Two\InvalidStateException;
use \SocialiteProviders\Manager\OAuth2\AbstractProvider;
use \SocialiteProviders\Manager\OAuth2\User;
class LineProvider extends AbstractProvider
{
public const IDENTIFIER = 'LINE';
/**
* The separating character for the requested scopes.
*
* @var string
*/
protected $scopeSeparator = ' ';
/**
* The scopes being requested.
*
* @var array
*/
protected $scopes = [
'openid',
'profile',
'email',
];
/**
* Get the authentication URL for the provider.
*
* @param string $state
* @return string
*/
protected function getAuthUrl($state)
{
return $this->buildAuthUrlFromBase(
'https://access.line.me/oauth2/v2.1/authorize',
$state
);
}
/**
* Get the token URL for the provider.
*
* @return string
*/
protected function getTokenUrl()
{
return 'https://api.line.me/oauth2/v2.1/token';
}
/**
* Get the raw user for the given access token.
*
* @param string $token
* @return array
*/
protected function getUserByToken($token)
{
$response = $this->getHttpClient()->get(
'https://api.line.me/v2/profile',
[
RequestOptions::HEADERS => [
'Authorization' => 'Bearer '.$token,
],
]
);
return json_decode((string) $response->getBody(), true);
}
/**
* Map the raw user array to a Socialite User instance.
*
* @param array $user
* @return \Laravel\Socialite\User
*/
protected function mapUserToObject(array $user)
{
return (new User())->setRaw($user)->map([
'id' => $user['userId'] ?? $user['sub'] ?? null,
'nickname' => null,
'name' => $user['displayName'] ?? $user['name'] ?? null,
'avatar' => $user['pictureUrl'] ?? $user['picture'] ?? null,
'email' => $user['email'] ?? null,
]);
}
// /**
// * Get the POST fields for the token request.
// *
// * @param string $code
// *
// * @return array
// */
// protected function getTokenFields($code)
// {
// return array_merge(parent::getTokenFields($code), [
// 'grant_type' => 'authorization_code',
// ]);
// }
/**
* @return \SocialiteProviders\Manager\OAuth2\User
*/
public function user()
{
if ($this->hasInvalidState()) {
throw new InvalidStateException();
}
$response = $this->getAccessTokenResponse($this->getCode());
if ($jwt = $response['id_token'] ?? null) {
$bodyb64 = explode('.', $jwt)[1];
$user = $this->mapUserToObject(json_decode(base64_decode(strtr($bodyb64, '-_', '+/')), true));
} else {
$user = $this->mapUserToObject($this->getUserByToken(
$token = $this->parseAccessToken($response)
));
}
$this->credentialsResponseBody = $response;
if ($user instanceof User) {
$user->setAccessTokenResponseBody($this->credentialsResponseBody);
}
return $user->setToken($this->parseAccessToken($response))
->setRefreshToken($this->parseRefreshToken($response))
->setExpiresIn($this->parseExpiresIn($response));
}
}
3. edit app/Providers/AppServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
$this->bootLineSocialite();
}
public function bootLineSocialite(): void
{
// // laravel Socialite 和 Socialite Line 有問題,就是 在初始載入不了
// // 看Socialite Line 作者還有在3星期前維謢,所以就不知道怎麼回事
// // https://medium.com/laravel-news/adding-auth-providers-to-laravel-socialite-ca0335929e42
$socialite = $this->app->make('Laravel\Socialite\Contracts\Factory');
$socialite->extend(
'line',
function ($app) use ($socialite) {
$config = config('services.line');
// https://github.com/SocialiteProviders/Line/blob/master/Provider.php
return $socialite->buildProvider(LineProvider::class, $config); // \SocialiteProviders\Line\Provider::class
}
);
}
}
4. routes/web.php
Route::get('/auth/redirect', function () {
return Socialite::driver('line')->redirect();
});
Route::get('/auth/callback', function () {
$user = Socialite::driver('line')->user();
dd($user);
});