php laravel 实现扫码登录
laravel 实现扫码登录
1.首先扫码端(移动端)必须登录了
2.进去登录页时,成生一个token,然后生成带token值的登录链接的二维码
3.前端定时异步请求服务前判断是否缓存 中 改token 是否有对应的用户信息
4.用户扫码,将用户的信息 与 缓存的token 对应
5.前端定时异步请求 获取 到 token 的用户信息,并将用户信息加入session,刷新页面
控制器
<?php
namespace App\Http\Controllers\PHP\Demo;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Endroid\QrCode\Color\Color;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelLow;
use Endroid\QrCode\QrCode;
use Endroid\QrCode\Label\Label;
use Endroid\QrCode\Logo\Logo;
use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
use Endroid\QrCode\Writer\PngWriter;
use Illuminate\Support\Facades\Redis;
use phpseclib3\Crypt\Random;
use Ramsey\Uuid\Uuid;
class QrCodeLoginController extends Controller
{
//登录页面
public function index(Request $request)
{
$user = $request->session()->get("user");
if ($user)
{
print_r($user);
return "<h1>已登录了</h1>";
}
return view('php.demo.qr_code_login.login');
}
//获取二维码
public function getQrCode(Request $request)
{
if ($request->session()->get("user"))
{
return response()->json(['code'=>0]);
}
$token = $request->session()->get('token');
if (!empty($token))
{
$this->delCode($token);
}
$token = (string)Uuid::uuid4();
$request->session()->put('token',$token);
$data = route("qr_code_login.login",['token'=>$token]);
$writer = new PngWriter();
// Create QR code
$qrCode = QrCode::create($data)
->setEncoding(new Encoding('UTF-8'))
->setErrorCorrectionLevel(new ErrorCorrectionLevelLow())
->setSize(300)
->setMargin(10)
->setRoundBlockSizeMode(new RoundBlockSizeModeMargin())
->setForegroundColor(new Color(0, 0, 0))
->setBackgroundColor(new Color(255, 255, 255));
$result = $writer->write($qrCode);
$full_name = "img/code/".md5($token).".png";
touch($full_name);
$result->saveToFile($full_name);
return response()->json(['code'=>1,'data'=> [ 'qr_code'=> "/".$full_name] ]);
}
public function delCode(string $token)
{
if (file_exists("img/code/{$token}.png"))
{
unlink("img/code/{$token}.png");
}
}
//检查是否扫码了
public function check(Request $request)
{
if ($request->session()->get("user"))
{
return response()->json(['code'=>1]);
}
$token = $request->session()->get('token');
if (!$token){
return response()->json(['code'=>0]);
}
$user = Cache::pull("user-token:{$token}");
if ($user)
{
$request->session()->put("user",$user);
$this->delCode($token);
}
return response()->json(['code'=>$user?1:0 ]);
}
//登录
public function login(Request $request)
{
if ( !$token = $request->input("token") )
{
return "<h1>token 无效</h1>";
}
$file = "img/code/".md5($token).".png";
if( !file_exists($file) )
{
return "<h1>token 无效1</h1>";
}
if ( time() - filectime($file) > 15 )
{
$this->delCode($token);
return "<h1>token 无效2</h1>";
}
/**
* 先要判断扫码这个端是否登录了,没登陆要登录后,再扫
*/
//模拟用户信息,真正用要改成自己的用户逻辑
$user = [
'user_id' => random_int(1,999),
'access_token' => md5(Uuid::uuid1()),
'name' => '随机用户',
];
Cache::put("user-token:{$token}",$user);
$this->delCode($token);
return "<h1>扫码登录成功</h1>";
}
}
?>
route.php
<?php
Route::prefix('php/demo/qr_code_login')->group(function () {
Route::get('/',[QrCodeLoginController::class,'index']);
Route::get('code',[QrCodeLoginController::class,'getQrCode'])->name('qr_code_login.code');
Route::get('login',[QrCodeLoginController::class,'login'])->name('qr_code_login.login');
Route::get('check',[QrCodeLoginController::class,'check'])->name('qr_code_login.check');
});
?>
页面代码
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<link rel="stylesheet" type="text/css" href="/css/vertical_horizontal_center.css">
<script src="/js/axios.js"></script>
<style>
body {
font-family: 'Nunito', sans-serif;
}
.title{
width:100px;
}
.v-h-center{
background-color: #FFF;
}
</style>
</head>
<body >
<div class="v-h-center">
<p >扫码登录</p>
<div>
<img class="qr_code_img" src="/img/loading.png" width="100%" height="100%" >
</div>
</div>
</body>
</html>
<script>
var img = document.querySelector('.qr_code_img');
get_code();
setInterval(function(){
get_code();
},15000);
function get_code()
{
let url = "{{ route('qr_code_login.code') }}";
img.src = "/img/loading.png";
axios.get(url)
.then(function (response) {
if (response && response.data.code == 1) {
let data = response.data.data;
if (data.qr_code)
{
img.src = data.qr_code;
}
}
})
.catch(function (error) {
console.log(error);
});
}
check();
function check()
{
let url = "{{ route('qr_code_login.check') }}";
axios.get(url)
.then(function (response) {
if (response && response.data.code == 1) {
alert("登录成功");
window.location.reload();
return;
}else{
setTimeout(function(){
check();
},1000);
}
})
.catch(function (error) {
console.log(error);
});
}
</script>