Created
August 29, 2022 15:26
-
-
Save sarfraznawaz2005/69a9bdf82a31cee2b24cfab3ab267910 to your computer and use it in GitHub Desktop.
Login via link - SSO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// code for central/sso server | |
Route::get('/login_to_client', function () { | |
$clientUrl = 'http://sso-client.test/login'; | |
// Assumptions: | |
// 1: Both server and client will use same encryption key | |
// 2: Same encryption algorithm will be used by both | |
$data = serialize(auth()->user()->first(['name', 'email'])->toArray()); | |
// https://www.php.net/manual/en/function.openssl-encrypt.php | |
$key = 'our-agreed-key'; | |
$cipher = 'AES-128-CBC'; | |
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($cipher)); | |
$ciphertext_raw = openssl_encrypt($data, $cipher, $key, 0, $iv); | |
$hmac = hash_hmac('sha256', $ciphertext_raw, $key, $asBinary = true); | |
$ciphertext = base64_url_encode($iv . $hmac . $ciphertext_raw); | |
return redirect()->to($clientUrl . '?data=' . $ciphertext); | |
})->middleware(['auth'])->name('login_to_client'); | |
// code for client | |
Route::get('login', function () { | |
if (request()->has('data')) { | |
// these must be saved in env, not hard coded in code | |
$key = 'our-agreed-key'; | |
$cipher = 'AES-128-CBC'; | |
$data = base64_url_decode(request()->get('data')); | |
$ivlen = openssl_cipher_iv_length($cipher); | |
$iv = substr($data, 0, $ivlen); | |
$hmac = substr($data, $ivlen, $sha2len = 32); | |
$ciphertext_raw = substr($data, $ivlen + $sha2len); | |
$decryptedText = openssl_decrypt($ciphertext_raw, $cipher, $key, 0, $iv); | |
$calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $asBinary = true); | |
if (hash_equals($hmac, $calcmac)) // timing attack safe comparison | |
{ | |
$data = unserialize($decryptedText); | |
if (is_array($data) && isset($data['name'])) { | |
// all good, create user session by saving his info in session | |
session()->put('logged_user_info', $data); | |
// user session created, redirect to home | |
return redirect()->to('/'); | |
} | |
} | |
} | |
// default 404 if no info passed | |
abort(404, 'Not Found'); | |
}); | |
// common functions | |
function base64_url_encode($input) { | |
return strtr(base64_encode($input), '+/=', '-_,'); | |
} | |
function base64_url_decode($input) { | |
return base64_decode(strtr($input, '-_,', '+/=')); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment