簡單說明
前端 傳 code 引數 ,都可以
weixin 傳 code 或者 access_token
apple 傳 id_token 或 access_token
在 EventServiceProvider
protected $listen = [
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
'SocialiteProviders\QQ\QqExtendSocialite@handle', // QQ登入
'SocialiteProviders\Weixin\WeixinExtendSocialite@handle', // 微信登入
],
];
AuthorizationsController
例項程式碼
<?php
namespace App\Http\Controllers\Api;
use App\Models\User;
use Faker\Generator;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
class AuthorizationsController extends Controller {
public function socialStore($type, Request $request) {
if (!in_array($type, ['weixin', 'qq', 'facebook', 'google', 'apple'])) {
return $this->failed('請求方式錯誤');
}
if (in_array($type, ['weixin', 'qq', 'facebook', 'google', ])) {
$driver = Socialite::driver($type);
try {
if ($code = $request->code) {
$response = $driver->getAccessTokenResponse($code);
$token = array_get($response, 'access_token');
} else {
$token = $request->access_token;
if ($type == 'weixin') {
$driver->setOpenId($request->openid);
}
}
$oauthUser = $driver->userFromToken($token);
}
catch(\Exception $e) {
return $this->failed('引數錯誤,未獲取使用者資訊');
}
} else {
// apple 登入
try {
if ($code = $request->code) {
$response = http('https://appleid.apple.com/auth/token', [
'grant_type' => 'authorization_code',
'code' => $code,
'redirect_uri' => config('services.apple.redirect') ,
'client_id' => config('services.apple.client_id') ,
'client_secret' => config('services.apple.client_secret') ,
]);
$id_token = $response->id_token;
} else {
$id_token = $request->access_token;
}
$oauthUser = json_decode(base64_decode(explode('.', $id_token) [1]));
}
catch(\Exception $e) {
return $this->failed('apple 引數錯誤');
}
}
$user = null;
switch ($type) {
case 'qq':
$user = User::query()->where('open_id', $oauthUser->getId())->first();
// 沒有使用者,預設建立一個使用者
if (!$user) {
$user = User::create([
'type' => User::TYPE_QQ,
'nickname' => $oauthUser->getNickname() ,
'avatar' => $oauthUser->getAvatar() ,
'open_id' => $oauthUser->getId() ,
]);
}
break;
case 'weixin':
$user = User::query()->where('open_id', $oauthUser->getId())->first();
// 沒有使用者,預設建立一個使用者
if (!$user) {
$user = User::create([
'type' => User::TYPE_WECHAT,
'nickname' => $oauthUser->getNickname() ,
'avatar' => $oauthUser->getAvatar() ,
'open_id' => $oauthUser->getId() ,
'sex' => $oauthUser['sex'] == 1 ? '男' : '女',
]);
}
break;
case 'facebook':
$user = User::query()->where('open_id', $oauthUser->getId())->first();
// 沒有使用者,預設建立一個使用者
if (!$user) {
$user = User::create([
'type' => User::TYPE_FACEBOOK,
'nickname' => $oauthUser->getName() ,
'avatar' => $oauthUser->getAvatar() ,
'open_id' => $oauthUser->getId() ,
]);
}
break;
case 'google':
$user = User::query()->where('open_id', $oauthUser->getId())->first();
// 沒有使用者,預設建立一個使用者
if (!$user) {
$user = User::create([
'type' => User::TYPE_GOOGLE,
'nickname' => $oauthUser->getName() ,
'avatar' => $oauthUser->getAvatar() ,
'open_id' => $oauthUser->getId() ,
]);
}
break;
case 'apple':
$user = User::query()->where('open_id', $oauthUser->sub)->first();
// 沒有使用者,預設建立一個使用者 Faker\Generator::class
$faker = app(Generator::class);
if (!$user) {
$user = User::create([
'type' => User::TYPE_APPLE,
'nickname' => array_key_exists('email', $oauthUser) ? $oauthUser->email : $faker->unique()->safeEmail,
'open_id' => $oauthUser->sub,
]);
}
break;
}
$token = Auth::guard('api')->setTTL(60 * 24 * 365)->fromUser($user);
return $this->respondWithToken($token)->setStatusCode(201);
}
protected function respondWithToken($token) {
return $this->success([
'access_token' => 'Bearer ' . $token,
'expires_in' => Auth::guard('api')->factory()->getTTL() ,
]);
}
}
apple 登入的 http 方法
function http($url, $params = false)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($params) {
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
} curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: application/json',
'User-Agent: curl', # Apple requires a user agent header at the token endpoint
]);
$response = curl_exec($ch);
return json_decode($response);
}
路由
Route::post('socials/{social_type}/authorizations', 'AuthorizationsController@socialStore')->name('api.socials.authorizations.store'); // 第三方登入
本作品採用《CC 協議》,轉載必須註明作者和本文連結