首页 > 其他分享 >10. Laravel api 认证

10. Laravel api 认证

时间:2023-02-28 11:47:01浏览次数:52  
标签:Laravel 10 password request auth token api php

Laravel api 认证

配套视频地址:https://www.bilibili.com/video/av74879198?p=3

原理

  1. 注册:用户注册成功后,随机生成长字符串作为 token,原生 token 返回给用户。哈希后的 token 存到数据库里。
  2. 登陆:用户使用账号密码登陆成功,随机生成长字符串作为 token,原生 token 返回给用户。哈希后的 token 存到数据库里。
  3. 认证:将用户传来的 token 进行哈希,然后去数据库中查找哈希后的 token ,找到了就认证成功,否则失败。

创建项目与配置

composer create-project --prefer-dist laravel/laravel laravel6
php artisan migrate
添加 api_token 字段,可空,唯一,默认 null。(可直接修改,也可以创建下面的代码片段然后迁移)
Schema::table('users', function ($table) {
    $table->string('api_token', 80)->after('password')
                        ->unique()
                        ->nullable()
                        ->default(null);
});

php artisan migrate

我们的例子还需要设置 email 可为空,因为我们以用户名作为认证的依据

设置模型可以操作 api_token 字段

# App\User.php
protected $fillable = [
    'name', 'email', 'password', 'api_token',
];

修改 api_token 这个名称

如果修改字段名称 api_token,请记得修改配置文件 config/auth.php 中的 storage_key

'api' => [
    'driver' => 'token',
    'provider' => 'users',
    'hash' => false,
    'storage_key' => 'api_token',
],

guard 设置为 api,hash 设置为 true

// config/auth.php

'defaults' => [
    'guard' => 'api',     // 默认 api 认证
    'passwords' => 'users',
],

'api' => [
    'driver' => 'token',
    'provider' => 'users',
    'hash' => true,       // 利用 SHA-256 算法哈希你的令牌
],

设置所有请求和响应都是 json 格式

请注意不要使用 php artisan make:request BaseRequest,这会使得你的 BaseRequest 继承 FormRequest,而我们要覆盖的是 Illuminate\Http\Request,所以我们应当继承的是 Request。

新建文件 app\Http\Requests\BaseRequest.php:

<?php

namespace App\Http\Requests;

use Illuminate\Http\Request;

class BaseRequest extends Request
{

    public function expectsJson()
    {
        return true;
    }
    public function wantsJson()
    {
        return true;
    }
}
// index.php
$response = $kernel->handle(
    $request = \App\Http\Requests\BaseRequest::capture()
);

编写 api 认证代码

Route::post('/register', 'Auth\ApiController@register');
Route::post('/login', 'Auth\ApiController@login');
Route::post('/refresh', 'Auth\ApiController@refresh');
Route::post('/logout', 'Auth\ApiController@logout');
php artisan make:controller Auth\ApiController
<?php

// email 设置可为空
// request 和 response 都是 json 格式
// api_token 设置可插入数据库    

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Str;

class ApiController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth')->except('login', 'register');
    }

    protected function username()
    {
        return 'name';
    }

    public function register(Request $request)
    {
        $this->validator($request->all())->validate();

        $api_token = Str::random(80);
        $data = array_merge($request->all(), compact('api_token'));
        $this->create($data);

        return compact('api_token');
    }

    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'max:255', 'unique:users',],
//            'email' => ['required', 'string', 'email', 'max:255',],
            'password' => ['required', 'string', 'min:8', 'confirmed'],
        ]);
    }

    protected function create(array $data)
    {
        return User::forceCreate([
            'name' => $data['name'],
//            'email' => $data['email'],
            'password' => password_hash($data['password'], PASSWORD_DEFAULT),
            'api_token' => hash('sha256', $data['api_token']),
        ]);
    }

    public function logout()
    {
        auth()->user()->update(['api_token' => null]);

        return ['message' => '退出登录成功'];
    }

    public function login()
    {
        $user = User::where($this->username(), request($this->username()))
            ->firstOrFail();

        if (!password_verify(request('password'), $user->password)) {
            return response()->json(['error' => '抱歉,账号名或者密码错误!'],
                403);
        }

        $api_token = Str::random(80);
        $user->update(['api_token' => hash('sha256', $api_token)]);

        return compact('api_token');
    }

    public function refresh()
    {
        $api_token = Str::random(80);
        auth()->user()->update(['api_token' => hash('sha256', $api_token)]);

        return compact('api_token');
    }
}

保护路由

middleware('auth')
middleware('auth:api')

# auth:api,editer 就表示 auth 中间件的 handle 方法的第三个参数值是 api, 第四个参数值是 editer。

# Auth 中间件来说,参数值 api 表示所使用的 guard 是 api

// Illuminate\Auth\Middleware\Authenticate->handle()

public function handle($request, Closure $next, ...$guards)
{
    $this->authenticate($request, $guards);

    return $next($request);
}

# 此处api与config/auth.php 配合使用,默认是web 用可以路由中用auth:api指定为api的配置  修改默认后可以用auth


给 Request 传 token

$response = $client->request('GET', '/api/user?api_token='.$token);

$response = $client->request('POST', '/api/user', [
    'headers' => [
        'Accept' => 'application/json',
    ],
    'form_params' => [
        'api_token' => $token,
    ],
]);

$response = $client->request('POST', '/api/user', [
    'headers' => [
        'Authorization' => 'Bearer '.$token,
        'Accept' => 'application/json',
    ],
]);

标签:Laravel,10,password,request,auth,token,api,php
From: https://www.cnblogs.com/fuqian/p/17163471.html

相关文章

  • 12. Laravel Passport 授权码模式
    LaravelPassport授权码模式配套视频地址:https://www.bilibili.com/video/av74879198?p=7哔哩哔哩提供一个“微信登陆”的链接,用户点击跳转到微信授权服务器。用户......
  • 11. Laravel Passport 密码模式
    LaravelPassport密码模式配套视频地址:https://www.bilibili.com/video/av74879198?p=5准备工作composercreate-project--prefer-distlaravel/laravellaravel6.......
  • Ubuntu下MySQL8.0报错:ERROR 1045 (28000): Access denied for user 'root'@'localhost
    问题在Ubuntu下,想要登录mysql数据库root@lgl:~#mysql-uroot-p 报错ERROR1045(28000):Accessdeniedforuser'root'@'localhost'(usingpassword:YES)......
  • Kubernetes部署的10个注意事项
    摘要容器开发有望在云中实现前所未有的可移植性和可扩展性。此外,DevOps开发和文化实践也有助于提升业务价值和响应能力。但是,在开始第一个容器开发项目之前,有一些问题......
  • 使用MetaWeblog api自动上传文章图片到cnblog
    由于我日常习惯用Typora来写笔记和博客,文章中的图片保存在本地,在发布文章到cnblog之前,希望能有一个自动化工具可以自动上传文章引用的图片到cnblog,获取图片链接,替换掉......
  • 尝试window10系统下使用appuim获取ios元素
    一般来说搞iOS手机的APP自动化需通过Mac电脑,但当前APP出图自动化测试平台是基于windows系统环境开发。如果因iOSAPP需要再重新搭建Mac的开发及测试环境,会很大程度上浪费资......
  • [gym102769D]Defend City
    以下描述部分方向代指该方向的塔,建议画图理解不妨假设左下的塔数\(\ge2\),这些塔覆盖区域构成阶梯形考虑阶梯的交点,若其被左上/右下覆盖,则总可以去掉其中一个左下换言之......
  • IDEA插件Apifox,一键自动生成接口文档!
    有关Apifox软件之前写过一篇文章:接口测试神器Apifox,亲测好用!如何一键自动生成数据库文档之前也写过一篇文章:数据库界的Swagger:一键生成数据库文档!一、Apifox插件的优......
  • restful的10个规范、序列化和反序列化的名词解释
    #概念REST全称是RepresentationalStateTransfer,中文意思是表述:表征性状态转移。RESTful是一种定义WebAPI接口的设计风格,尤其适用于前后端分离的应用模式中--------......
  • 10. Kubernetes - DNS
    服务发现通过Service知道了后端的Pod服务可以通过ClusterIP代理出来让其他服务能够访问到。但也存在一个问题,Service可能会被更新或者重建,下一次的IP可能就变了......