ホームページ  >  記事  >  PHPフレームワーク  >  jwt認証を使用したthinkphp6の詳細な例

jwt認証を使用したthinkphp6の詳細な例

WBOY
WBOY転載
2022-06-24 12:57:124569ブラウズ

この記事では、主に jwt 認証を使用する際の問題点を紹介する thinkphp に関する関連知識を紹介します。一緒に見ていきましょう。皆様のお役に立てれば幸いです。

jwt認証を使用したthinkphp6の詳細な例

推奨学習: 「PHP ビデオ チュートリアル

thinkphp6 using jwt

  1. クライアントはユーザー名とパスワードを使用してログインをリクエストします。
  2. サーバーはリクエストを受信し、ユーザー名とパスワードを検証します。
  3. 検証に成功すると、サーバーはトークンを発行し、トークンをクライアントに返します。
  4. トークンを受信した後、クライアントはそれを Cookie に入れるなどして保存できます。
  5. クライアントは、サーバーにリソースを要求するたびに、サーバーによって発行されたトークンを保持する必要がありますこれは Cookie に含めることも、ヘッダーには
  6. #サーバーがリクエストを受信し、クライアント リクエストに含まれるトークンを検証します。検証が成功すると、リクエスト データをクライアントに返します
jwt 拡張機能をインストールします

composer require firebase/php-jwt

インストール後、ベンダー ディレクトリの firebase フォルダーに移動します

jwt認証を使用したthinkphp6の詳細な例

エンコード メソッドとデコード メソッドを呼び出しますJWT でトークンの生成とトークンの検証を行う

プロジェクトの app ディレクトリにある common.php グローバル ファイルを使用し、パブリック メソッドにします。複数のアプリケーションがあるため、以下の common.php に記述しました。 api. 独自のニーズに応じて適切に調整できます

jwt認証を使用したthinkphp6の詳細な例

最初に JWT を導入し、次に署名検証と検証トークンを生成する 2 つのメソッドを記述します。
<?phpuse  \Firebase\JWT\JWT;use Firebase\JWT\Key;// 应用公共文件/**
 * 生成验签
 * @param $uid 用户id
 * @return mixed
 */function signToken($uid){
    $key=&#39;abcdefg&#39;;         //自定义的一个随机字串用户于加密中常用的 盐  salt
    $token=array(
        "iss"=>$key,        //签发者 可以为空
        "aud"=>'',          //面象的用户,可以为空
        "iat"=>time(),      //签发时间
        "nbf"=>time(),      //在什么时候jwt开始生效
        "exp"=> time()+30,  //token 过期时间
        "data"=>[           //记录的uid的信息
            'uid'=>$uid,
        ]
    );
    $jwt = JWT::encode($token, $key, "HS256");  //生成了 token
    return $jwt;}/**
 * 验证token
 * @param $token
 * @return array|int[]
 */function checkToken($token){
    $key='abcdefg';     //自定义的一个随机字串用户于加密中常用的 盐  salt
    $res['status'] = false;
    try {
        JWT::$leeway    = 60;//当前时间减去60,把时间留点余地
        $decoded        = JWT::decode($token, new Key($key, 'HS256')); //HS256方式,这里要和签发的时候对应
        $arr            = (array)$decoded;
        $res['status']  = 200;
        $res['data']    =(array)$arr['data'];
        return $res;

    } catch(\Firebase\JWT\SignatureInvalidException $e) { //签名不正确
        $res['info']    = "签名不正确";
        return $res;
    }catch(\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用
        $res['info']    = "token失效";
        return $res;
    }catch(\Firebase\JWT\ExpiredException $e) { // token过期
        $res['info']    = "token过期";
        return $res;
    }catch(Exception $e) { //其他错误
        $res['info']    = "未知错误";
        return $res;
    }}

jwt を使用してトークンを生成します
    /**
     * 使用jwt生成token字符串
     */
    public function setJwtToken()
    {
        $uid = input('uid'); // 接收生成token字符串 如:123
        $token = signToken($uid);
        // 生成字符串: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhYmNkZWZnIiwiYXVkIjoiIiwiaWF0IjoxNjQxNDUwMTU0LCJuYmYiOjE2NDE0NTAxNTcsImV4cCI6MTY0MTQ1NzM1NCwiZGF0YSI6eyJ1aWQiOiIxMjMifX0.I_GAkMsOhtEpIPkizCuQA-b9H6ovSovWx0AwAYI-b0s
        echo $token;die;
    }

    /**
     * 使用jwt验证token字符串
     */
    public function checkJwtToken()
    {
        $token  = input('token'); // 接收生成token字符串
        $result = checkToken($token);
        // Array ( [status] => 200 [data] => Array ( [uid] => 123 ) )
        print_r($result);die;
    }

ユーザー コントローラーを作成します
<?phpdeclare  (strict_types = 1);namespace app\api\controller;use think\facade\Db;use think\Request;class User{
    public function login(Request $request)
    {
        if ($request->isPost()){
            $username = $request->param('username','','trim');
            $password = $request->param('password','','trim');

            //查询数据库
            $user = Db::name('user')->where('username',$username)->find();

            if (!$user){
                return json(['status' => 'fail','msg' => '用户名不存在']);
            }
            if ($user['password']!==md5($password)){
                return json(['status' => 'fail','msg' => '密码错误']);
            }
            $getToken = $this->token($user);
            return json(['status' => 'success','msg' => '登陆成功','token' => $getToken]);
        }
    }
    public function token($user)
    {
        $uid = $user['username']; // 接收生成token字符串 如:123
        $token = signToken($uid);
        dd($token);
    }
    /**
     * 验证token
     */
    public function chToken()
    {
        $token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhYmNkZWZnIiwiYXVkIjoiIiwiaWF0IjoxNjQ4MDkwMDkyLCJuYmYiOjE2NDgwOTAwOTIsImV4cCI6MTY0ODA5MDEyMiwiZGF0YSI6eyJ1aWQiOiJcdTVmMjBcdTRlMDlcdTk4Y2UifX0.oJFpNcZ6stMymOCbD-meX0IPEIYLYNcwKxhMItF2cMw';
        $result = checkToken($token);
        // Array ( [status] => 200 [data] => Array ( [uid] => 123 ) )
        print_r($result);die;
    }}

ユーザーは正常にログインし、フロントエンドトークンに戻り、フロントエンドはトークンを保存し、次のリクエスト中にヘッダーにトークンを運びます。バックエンドはトークンを受け入れ、ミドルウェアで検証します

API ミドルウェアを作成します
<?phpdeclare  (strict_types = 1);namespace app\middleware;class Api{
    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        //toke 合法性验证
        $header = $request->header();
        //判读请求头里有没有token
        if(!isset($header['token'])){
            return json(['code'=>440,'msg'=>'request must with token']);
        }
        $token = $header['token'];

        try {
            // token 合法
            $token = checkToken($token);
        }catch (\Exception $e){
            return json(['code'=>440,'msg'=>'invalid token']);
        }

        return $next($request);
    }}

最後に、トークンの有効期限の問題に対処する方法は 2 つあります。1 つ目は、トークンの有効期限が切れないようにトークンの時間を長く設定することです。ただし、これには欠点があります。クライアントがこのトークンを取得すると、キーを取得したことと同じになり、主導権はユーザーの手に渡ります。したがって、この解決策はお勧めできません。 2 つ目はバックエンド処理です。トークンの有効期限が切れると、トークンが再取得され、新しいトークンがフロントエンドに渡されます。フロントエンドは新しいトークンを保存し、元のトークンを置き換え、次のリクエストで新しいトークンを送信します。 .トークンリクエスト。

学ぶことと投げることが大好きなプログラマーのFengfengです。

推奨学習: 「

PHP ビデオ チュートリアル

以上がjwt認証を使用したthinkphp6の詳細な例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。