柔晶美网络工作室

柔晶美网络工作室,倾心于web技术的博客站点

关注我 微信公众号

您现在的位置是: 首页 > 博客日记

laravel8.x用户名或手机多字段登录,以及laravel/sanctum构造api登录方法

2021-05-26 admin laravel  1423

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>&nbsp;用户名/手机号</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']);
});

记录完毕。

文章评论


需要 登录 才能发表评论
热门评论
0条评论

暂时没有评论!