用 Laravel 实现授权码登录功能 - 用户认证
需求
- 通过webhook接受推送过来的数据,将数据中含有邮箱地址的信息插入到用户表;
- 用户使用系统中的某些功能(比如:编辑仓库配置信息),需要验证用户是否登录,但不需要用户设置密码;
- 由系统向邮箱中发送一个授权码链接,点击链接后验证通过后,得到授权则可以使用系统的各项功能;
分析
也就是说,验证用户是否登录不需要输入账户和密码,只需要给他一个授权码生成的链接,邮箱能接收到授权链接,并且授权码和数据库中的授权码一致,则算验证通过。
具体实现步骤
1.数据表结构
表中的邮箱是从webhook推送过来的信息中提取后存到author表中的。可以看到password字段是空的,默认是没有密码的,当然没有密码是没有办法验证通过的
2.代码实现
2.1.在需要权限的URI上增加认证,路由调整如下:
Route::group(['prefix' => 'repo'], function(){
Route::get('/view/{repoid}', 'Repo@view');
Route::get('/edit/{repoid}', ['middleware' => 'auth', 'uses' => 'Repo@edit']);
Route::post('/update', 'Repo@update');
});
代码片段说明:当用户编辑仓库的配置文件时,验证用户是否已经登录
2.2.使用系统的功能需要向邮箱中发送授权链接。界面如下:
实现代码如下:
/**
* 发送授权链接
*/
public function postoken(Request $request)
{
//表单验证
$rules = [
'author' => 'required|email|disabled|max:255'
];
$message = [
'required' => '请填写邮箱地址',
'email' => '邮箱地址不合法',
'disabled' => '邮箱地址不存在,无法发送链接',
'max' => '长度不能超过 :max 个字符'
];
$validator = Validator::make($request->all(), $rules, $message);
if ($validator->fails()) {
return redirect('/auth/email')
->withErrors($validator)
->withInput();
}
//获取用户名
$email = $request->input('author');
$tmp = explode('@', $email);
$name = $tmp[0];
$user = array(
'email' => $email,
'name' => $name
);
$six_digit_random_number = mt_rand(100000, 999999);
//将随机数写入数据表
$author = Author::where('author', $email)->first();
$author->password = Hash::make($six_digit_random_number);
$author->save();
//发送邮件
Mail::send('emails.test', ['token' => $six_digit_random_number, 'email' => $email], function($message) use ($user) {
$message->from('tixing@gongchang.com', 'wefly')
->to($user['email'], $user['name'])
->subject('您的授权链接');
});
return view('postauth');
}
代码片段说明: 验证表中有存在用户输入的邮箱后,向表中的记录的password初始化一个6位数的密码,并将授权链接发送到邮箱中
初始化后的数据表,如图:
2.2.3.用户收到授权码的邮件
邮箱模版使用了https://github.com/Snowfire/Beautymail
2.2.4.用户点击授权链接进行验证
路由代码:
//发送用户验证授权链接
Route::group(['prefix' => 'auth'], function(){
Route::get('email', 'Home@email');
Route::post('postoken', 'Home@postoken');
Route::get('signin/{token}', 'Home@signin');
});
逻辑代码:
/**
* 验证授权链接
*/
public function signin(Request $request, $token)
{
$email = $request->get('email');
if (Auth::attempt(['author' => $email, 'password' => $token])) {
return redirect('/');
} else {
echo '授权码错误,验证失败';
}
}
本帖已被设为精华帖!
本帖由 Summer
于 8年前 加精
推荐文章: