在 laravel 中使用第三方登入並整合 Auth Facade
在 legency 專案上要變換登入要考量的事很多,其中一個情況就是 blade 大量使用 Auth Facade 做 UI 的呈現變化,加上第三方登入都跟你 token 來 token 去,不熟 auth 還真不知道怎麼下手。
這邊提出在這種情況下比較無痛轉移的方法
在 laravel 中修改驗證時有幾個地方要改,以下分別列出並提供範例
- config/auth.php
<?php
...
'providers' => [
'users' => [
'driver' => 'custom-driver',
]
]
...
- AuthServiceProvider.php
you can use php artisan
to create provider
<?php
public function boot() {
...
Auth::provider('custom-driver', function ($app, array $config) {
return new YourCustomAuthProvider();
});
}
- YourCustomAuthProvider.php
<?php
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Auth\GenericUser;
class YourCustomAuthProvider implements \Illuminate\Contracts\Auth\UserProvider
{
// implement all contrat
// below is sample
public function retrieveById($identifier)
{
return $this->getUser($identifier);
}
public function retrieveByToken($identifier, $token)
{
$user = $this->getUser($identifier);
return isset($user['remember_token']) && $user['remember_token'] == $token ? $user : null;
}
public function updateRememberToken(Authenticatable $user, $token)
{
Session::put('remember_token', $token);
}
public function retrieveByCredentials(array $credentials)
{
$token = $this->getAccessToken();
if(!$token) {
// invalid token actions here
}
$data = $this->getUserData($token);
return new GenericUser($data);
}
public function validateCredentials(Authenticatable $user, array $credentials)
{
return yourCredentialsIsValidate() ? true: false;
}
}
- YourLoginController.php
<?php
...
use Illuminate\Auth\GenericUser;
...
public function login(Request $request)
{
$data = getTokenAndUserDataFromThirdParty();
// the key-point is here
Auth::guard('web')->login(new GenericUser(['id' => $data['email']]))
// then you keep your facade works as usual
}
補充:使用 redis 實現 sso
- redis retrive session
<?php
...
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Auth;
use SessionHandlerInterface;
class RedisSessionServices implements SessionHandlerInterface
{
public function open($savePath, $sessionName)
{
return true;
}
public function close()
{
return true;
}
public function read($sessionId)
{
return Redis::get($this->prefixCheck($sessionId));
}
public function write($sessionId, $data)
{
// can add auth check if needed
Redis::set($this->prefixCheck($sessionId), $data, 'EX', $expireTime);
return true;
}
public function destroy($sessionId)
{
Redis::del($this->prefixCheck($sessionId));
return true;
}
public function gc($lifetime)
{
return true;
}
/**
* laravel 原生會帶 :session:
*/
private function prefixCheck($sessionId)
{
$prefix = env('REDIS_PREFIX') . ':session:';
if (strpos($sessionId, $prefix) === false) {
$sessionId = $prefix . $sessionId;
}
return $sessionId;
}
}
Reference
發佈時間
2020-6-16