Laravel study notes (24) laravel6 Authentication and Authorization (api)

Original: https://qianjinyike.com/laravel-api-%E8%AE%A4%E8%AF%81/

When writing exclusively for API service Laravel applications, and all responses are in JSON format, using the API certification

  1. principle

Registration: User registration is successful, generating long random string as a token, a native token back to the user cookie. After the token hash stored in a database.
Online: user account password is successful, generating long random string as a token, a native token back to the user cookie. After the token hash stored in a database.
Authentication: The user came token hash, then go through the database to find the hash stored in the token before comparison, are equal, the authentication is successful, otherwise fail

  1. Api_token additional database fields and add the white list in the User model
$table->string('api_token', 80)->unique()->nullable()->default(null);
  1. Modify the name api_token
// 如果修改字段名称 api_token,请记得修改配置文件 config/auth.php 中的 storage_key

'api' => [
    'driver' => 'token',
    'provider' => 'users',
    'hash' => false,
    'storage_key' => 'api_token',
],
  1. Modify the configuration, change the default web authentication API certification

guard set api, hash is set to true

// config/auth.php

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

'api' => [
    'driver' => 'token',
    'provider' => 'users',
    'hash' => true,       // 利用 SHA-256 算法哈希你的令牌
],
  1. Write BaseRequest
    First, we need to build a BaseRequest to rewrite Illuminate \ Http \ Request, modify the default priority using the JSON response:
app/Http/Requests/BaseRequest.php

<?php
namespace App\Http\Requests;

use Illuminate\Http\Request;

// 注意 继承于Request而不是FormRequest,所以不能直接用artisan make:request生成
class BaseRequest extends Request
{
    public function expectsJson()
    {
        return true;
    }
    public function wantsJson()
    {
        return true;
    }
}
  1. Replace BaseRequest
// 在 public/index.php 文件中,将 \Illumiate\Http\Request 替换为我们的 BaseRequest,如下:

$response = $kernel->handle(
    $request = \App\Http\Requests\BaseRequest::capture()
);

PS: After the fifth step and the sixth step execution, all responses are application / json, including errors and exceptions

  1. Json return method

Method 1: Use json () method #

return response()->json([ 
    'name' => 'Abigail', 
    'state' => 'CA' 
]);

JSON () method may be Content-Type header is set to application / json, while the use of built-in functions PHP json_encode, turn into the array JSON format.

Second way: direct returns an array

$arr = [1,2];
return $arr;

This method returns the Content-Type is text / html.

The difference between these two methods:
Method 1 http Response Headers the Content-Type is application / json.
Second way of http Response Headers Content-Type is text / html.

  1. Generated 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');
    }

    // 默认使用email进行验证
    protected function username()
    {
        // return 'name';
        return 'email';
    }

	// 注册的时候生成一个哈希过的api_token
    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'],
        ]);
//        等效于
//        $request->validate([
//            ....
//        ])
    }

    protected function create(array $data)
    {
        // 实际上,属性值是否可以批量赋值需要受 fillable 或 guarded 来控制,如果我们想要强制批量赋值可以使用 forceCreate
        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()
    {
        // web登出是Auth::logout()
        auth()->user()->update(['api_token' => null]);

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

	// 先进行登录验证,之后重新生成一个哈希过的api_token并更新User表
    public function login()
    {
        $user = User::where($this->username(), request($this->username()))
            ->firstOrFail();

        // 将request('password')哈希后与$user->password进行比对
        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');
    }

	// 重新生成一个哈希过的api_token并更新User表
    public function refresh()
    {
        $api_token = Str::random(80);
        auth()->user()->update(['api_token' => hash('sha256', $api_token)]);

        return compact('api_token');
    }
}
  1. routing
Route::post('/register', 'Auth\ApiController@register');
Route::post('/login', 'Auth\ApiController@login');
Route::post('/refresh', 'Auth\ApiController@refresh');
Route::post('/logout', 'Auth\ApiController@logout');
  1. expire date

At this time the token is not expired, the permanent presence

If you want token has an expiration time, will join the expiration time field in the table, and then create a new middleware, the middleware in determining whether the current time is greater than the expiration date, if it is larger than it authentication fails.

Published 40 original articles · won praise 0 · Views 767

Guess you like

Origin blog.csdn.net/qj4865/article/details/104333654