laravel默认是邮箱登录,如果仅仅修改为用户名,只需要在
app/Http/Controllers/Auth/LoginController.php
文件中添加如下方法即可:
public function username(){
return 'name';
}
但有时我们需要设置为:输入用户名或手机号都可以登录,这时,我们需要这样修改:
//用户名或手机登录
protected function attemptLogin(Request $request)
{
return collect(['name', 'phone'])->contains(function ($value) use ($request) {
$account = $request->get($this->username());
$password = $request->get('password');
return $this->guard()->attempt([$value => $account, 'password' => $password], $request->filled('remember'));
});
}
public function username()
{
return 'account';
}
然后修改前端模板:
<div class="form-group row">
<label for="account" class="col-md-4 col-form-label text-md-right"><em style="color: red;">*</em> 用户名/手机号</label>
<div class="col-md-6">
<input id="account" type="text" class="form-control @error('account') is-invalid @enderror" name="account" value="{{ old('account') }}" required autocomplete="account" autofocus>
@error('account')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
这样就实现了多字段登录了,输入用户名或手机号,再输入密码即可。
API登录,以前用laravel/passport,仅仅用来微信和APP登录,感觉有些大材小用,因此准备用Sanctum这个轻量的认证来取代。laravel Sanctum 是为了解决两个独立问题而生:
API 令牌
首先,它是一个简单的包,用于向用户发出 API 令牌,而不涉及 OAuth。这个功能的灵感来自 GitHub 的「访问令牌」。例如,假设应用程序的「帐户设置」有一个界面,用户可以在其中为其帐户生成 API 令牌。您可以使用 Sanctum 来生成和管理这些令牌。这些令牌通常有很长的过期时间 (以年计),当然用户是可以随时手动撤销它们。
Laravel Sanctum 的这个特性是通过将用户 API 令牌存储在单个数据库表中,并通过包含了有效 API 令牌的 Authorization 标头对传入请求进行身份验证而实现的。
SPA 身份验证
Sanctum 提供了一种简单的方法来认证需要与基于 Laravel 的 API 进行通信的单页应用程序 (SPAs)。这些 SPA 可能与 Laravel 应用程序存在于同一仓库中,也可能是一个完全独立的仓库,例如使用 Vue CLI 创建的单页应用程序。
对于此功能,Sanctum 不使用任何类型的令牌。相反,Sanctum 使用 Laravel 内置的基于 cookie 的会话身份验证服务。这提供了 CSRF 保护,会话身份验证以及防止因 XSS 攻击而泄漏身份验证凭据。仅当传入请求来自您自己的 SPA 前端时,Sanctum 才会尝试使用 Cookie 进行身份验证。
安装:
composer require laravel/sanctum
生成配置文件,可以设置token过期时间等
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
执行迁移:
php artisan migrate
在app/Http/Kernel.php 文件中将 Sanctum 的中间件添加到你的 api 中间件组中:
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
'api' => [
EnsureFrontendRequestsAreStateful::class,
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
api添加相应路由,控制器登录代码:
//app账号密码登录
public function login(Request $request){
$data = $request->validate([
'phone' => 'required|numeric',
'password' => 'required'
]);
$user = User::where('phone', $request->phone)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
return response([
'message' => ['账号或密码错误']
], 404);
}
$user['token'] = $user->createToken('MyApp')->plainTextToken;
return response()->json(['code' => 200,'user' => $user,'msg' => '登录成功'], 200);
}
//小程序微信快捷登录
public function wxlogin(Request $request){
$fh = $this->app->auth->session($request->code);
if(!$fh) return response()->json(['code'=>500,'msg' => 'error']);
if($openid = $fh['openid']){
$unionid = $fh['unionid'] ?? '';
if($user = User::where('xcxopenid',$openid)->first()){
$user['token'] = $user->createToken('MyApp')->plainTextToken;
return response()->json(['code' => 200,'user' => $user,'msg' => '登录成功']);
}else{
//未注册,自动注册
$phone = mt_rand(11111111111,99999999999);
$user = User::create(['name'=>$phone,'phone'=>$phone,'email'=>$phone.'@qq.com','uuid'=>$unionid,'xcxopenid'=>$openid,'password'=>Hash::make(123456),'email_verified_at'=>now()]);
$user['token'] = $user->createToken('MyApp')->plainTextToken;
return response()->json(['code' => 200,'user' => $user,'msg' => '注册成功']);
}
}
}
登录功能基本完成,如果要将相关路由加入验证,可设置路由组,并用中间件保护:
Route::middleware('auth:sanctum')->group(function () {
Route::post('cx/{id}', [ApiController::class, 'cxtj']);
});
记录完毕。