Hôm nay mình có code bằng laravel 8 kết nối auth openid của haravan. Chia sẽ lại cho anh em nào cần làm app bằng php ở HARAVAN
Cần làm:
1. Xem Docs haravan: https://docs.haravan.com/blogs/omni/login-and-logout-haraaccount
2. Đăng ký 1 tài khoản partner
- Link https://partners.haravan.com
3. Tạo 1 APP trên haravan
- Link tạo https://developers.haravan.com/
4. Bắt đầu code
- Đầu tiên tạo cài đặt laravel/socialite . Có thể xem hướng dẫn cài đặt của trang chính https://laravel.com/docs/8.x/socialite
composer require laravel/socialite
composer require laravel/socialite
- Tạo 1 app/Providers/HaravanProvider.php
<?php
namespace App\Providers;
use Laravel\Socialite\Two\AbstractProvider;
use Laravel\Socialite\Two\ProviderInterface;
use Laravel\Socialite\Two\User;
use Illuminate\Support\Arr;
class HaravanProvider extends AbstractProvider implements ProviderInterface
{
protected $scopeSeparator = ' ';
protected $scopes = [
'openid',
'org',
'phone',
'email',
'userinfo',
'profile',
'com.read_customers',
'com.write_customers',
'com.read_products',
'com.write_products',
'com.read_orders',
'com.write_orders',
];
/**
* Get the authentication URL for the provider.
*
* @param string $state
* @return string
*/
protected function getAuthUrl($state)
{
return $this->buildAuthUrlFromBase('https://accounts.haravan.com/connect/authorize', $state);
}
/**
* Get the token URL for the provider.
*
* @return string
*/
protected function getTokenUrl()
{
return 'https://accounts.haravan.com/connect/token';
}
protected function getTokenFields($code)
{
return Arr::add(
parent::getTokenFields($code),
'grant_type',
'authorization_code'
);
}
/**
* Get the raw user for the given access token.
*
* @param string $token
* @return array
*/
protected function getUserByToken($token)
{
$response = $this->getHttpClient()->get('https://accounts.haravan.com/connect/userinfo', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token,
],
]);
return json_decode($response->getBody(), true);
}
protected function mapUserToObject(array $user)
{
return (new User())->setRaw($user)->map([
'id' => Arr::get($user, 'sub'),
'name' => Arr::get($user, 'name'),
'email' => Arr::get($user, 'email'),
'locale' => Arr::get($user, 'locale'),
'role' => Arr::get($user, 'role'),
'org_id' => (int)Arr::get($user, 'orgid'),
'org_name' => Arr::get($user, 'orgname'),
]);
}
}
- Trong file app/Providers/AppServiceProvider.php
public function boot()
{
//......
$this->bootHaravanSocialite();
}
private function bootHaravanSocialite()
{
$socialite = $this->app->make('Laravel\Socialite\Contracts\Factory');
$socialite->extend('haravan', function ($app) use ($socialite) {
$config = $app['config']['services.haravan'];
return $socialite->buildProvider(HaravanProvider::class, $config);
});
}
- File config/services.php thêm vào config haravan
'haravan' => [
'client_id' => env('HARAVAN_ACCESS_KEY_ID'),
'client_secret' => env('HARAVAN_SECRET_ACCESS_KEY'),
'redirect' => env('HARAVAN_REDIRECT')
]
- File config/session.php cấu hình lại same_site
'same_site' => 'none',
- File app/Http/Kernel.php enable session. Remove comment \Illuminate\Session\Middleware\AuthenticateSession::class,
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
- File routes/web.php thêm mới
Route::get('/login', [HaravanAuthController::class, 'redirectToProvider'])->name('login');
Route::post('/login_callback', [HaravanAuthController::class, 'handleProviderCallback']);
- Chổ này lưu ý khi redirect về coi chừng bị csrf nên vào file app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
'login_callback'
];
- File controller xử lý thì thêm 2 function HaravanAuthController.php xem thêm đầy đủ link github của mình.
- Trong đây sau khi lấy được access_token mình lưu vào table user. Thông tin mình lấy được gồm: id, name, email, locale, role, org_id, org_name.
- Nó được mapUserToObject trong file HaravanProvider.php
public function redirectToProvider()
{
if (!empty(auth()->id())) {
return redirect('dashboard');
}
$params = [
'response_mode' => 'form_post',
'response_type' => 'code id_token',
'nonce' => Str::random(6)
];
return Socialite::driver('haravan')->with($params)->redirect();
}
public function handleProviderCallback()
{
$user = Socialite::driver('haravan')->user();
$dataUser = [
'email' => $user->getEmail(),
];
$dataValue = [
'name' => $user->getName(),
'password' => $user->token,
'remember_token' => $user->token,
];
$myUser = User::query()->updateOrCreate($dataUser, $dataValue);
if (Auth::login($myUser)) {
return route('dashboard');
}
return redirect('/');
}
- File .env thêm vào 3 biến môi trường
HARAVAN_ACCESS_KEY_ID=fc73d4219e97f5123
HARAVAN_SECRET_ACCESS_KEY=25f332c6ddd94b36cc1123123
HARAVAN_REDIRECT=https://simpleweb.test/login_callback
5. Bây giờ test thử
- Mình có tích hợp css page bootstrap cho nó ok xíu. Có thể click link
- Ở đây mình đang add hosts https://simpleweb.test/login Anh em có thể dùng ngork theo hướng dẫn của haravan
6. Sau khi auth thành công
- Đây là màn hình kết nối thành công mình cho redirect về dashboad
Nhìn chung sử dụng socialite extend lại thì có vẻ đơn giản hơn nhiều.
Ngoài ra có thể viết dạng package như https://socialiteproviders.com/usage/
Mình đang làm basic hết có thể cho anh em hiểu cách tiếp cần OpenID đã phần 1 số bạn dev mới sẽ còn khó hiểu về vấn đề này.
Mình có up code trên https://github.com/tinhnguyenvan/laravel-auth-haravan anh em có thể down về xem thử.