zoukankan      html  css  js  c++  java
  • JWT生成Token做登录校验

    一、JWT的优点

    1、服务端不需要保存传统会话信息,没有跨域传输问题,减小服务器开销。

    2、jwt构成简单,占用很少的字节,便于传输。

    3、json格式通用,不同语言之间都可以使用。

    二、使用JWT进行用户登录鉴权的流程

    ① 用户使用用户名密码来请求服务器

    ② 服务器进行验证用户的信息

    ③ 服务器通过验证发送给用户一个token

    ④ 客户端存储token,并在每次请求时附送上这个token值

    ⑤ 服务端验证token值,并返回数据

    三、php-jwt库下载地址

    1、通过composer下载:

    composer require firebase/php-jwt

    2、github下载地址:https://github.com/firebase/php-jwt

    3、百度云下载地址:https://pan.baidu.com/s/1lpyz8oKf_CM-kOi7MGVoPg

    提取码:wyq0

    三、简单示例

    1、登录页面代码:login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="showpage">
        <div class="form-group">
            <label for="username">用户名</label>
            <input type="text" class="form-control" id="username" placeholder="请输入用户名">
        </div>
        <div class="form-group">
            <label for="password">密码</label>
            <input type="password" class="form-control" id="password" placeholder="请输入密码">
        </div>
        <button type="submit" id="sub-btn" class="btn btn-default">登录</button>
    
        <br/>
        <p class="bg-warning" style="padding: 10px;">演示用户名和密码都是<code>demo</code></p>
    </div>
    </body>
    </html>
    
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    <script>
        $('#sub-btn').on('click',function (e) {
            $.ajax({
                type: 'post',
                url: './user.php?action=login',
                data: {
                    username:$('#username').val(),
                    password:$('#password').val(),
                },
                dataType:'json',
                success: function (data, status, xhr) {
                    alert(data.msg);
                    if(data.code==200){
                        //将jwt存储到本地
                        var jwt = xhr.getResponseHeader('Authorization');
                        localStorage.setItem("jwt", jwt);
                        //跳转登录成功的页面
                        window.location.href="./user.html";
                    }
                }
            });
        });
    </script>

    2、登录成功后页面代码:user.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h3>你已成功登陆</h3>
    </body>
    </html>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    <script>
        $.ajax({
            type: 'post',
            url: './user.php',
            headers: {
                'Authorization': localStorage.getItem("jwt")
            },
            data: {},
            async: true,
            dataType: 'json',
            success: function (data, status, xhr) {
                if(data.code!=200){
                    //jwt验证失败
                }
                //如果响应头接收到了Authorization,则将本地jwt更新
                if (xhr.getResponseHeader('Authorization')) {
                    localStorage.setItem("jwt", jwt);
                }
            },
            error: function () {
                alert('error');
            }
        });
    </script>

    3、后端PHP代码:user.php

    <?php
    /*
     使用composer安装php-jwt,接收到登录用户名和密码后,PHP验证用户名和密码是否正确
    (实际开发中应该结合数据库,从数据库里拿用户名和密码比对,本实例为了演示只做简单验证),
    如果用户名和密码准确无误,那么就签发token,在token中,我们可以定义token的签发者
    、过期时间等等,并返回给前端。注意在签发token时,我们需要定义一个密钥,这个密钥是一个私钥,
    实际应用中是保密的不可告诉别人。
     * */
    require_once './php-jwt-master/src/JWT.php';
    
    use FirebaseJWTJWT;
    
    define('KEY', '1gHuiop975cdashyex9Ud23ldsvm2Xq'); //密钥
    
    $action = isset($_GET['action']) ? $_GET['action'] : '';
    if ($action == 'login') {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $username = htmlentities($_POST['username']);
            $password = htmlentities($_POST['password']);
            $data     = ['userid' => 1, 'username' => $username];
    
            if ($username == 'demo' && $password == 'demo') { //用户名和密码正确,则签发tokon
                $nowtime = time();
                $token   = [
                    'iss'  => 'http://www.helloweba.net', //签发者
                    'aud'  => $_SERVER['REMOTE_ADDR'], //jwt所面向的用户
                    'iat'  => $nowtime, //签发时间
                    'exp'  => $nowtime + 600, //过期时间-10min
                    'data' => $data
                ];
                $jwt     = JWT::encode($token, KEY);
                header("Authorization:$jwt");
                $res = array('code' => 200, 'msg' => '登录成功', 'data' => $data);
            } else {
                $res = array('code' => 300, 'msg' => '登录失败');
            }
        }
        die(json_encode($res));
    
    } else {
        $jwt = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : '';
        if (empty($jwt)) {
            $res = array('code' => 301, 'msg' => 'You do not have permission to access.');
            die(json_encode($res));
        }
        try {
            JWT::$leeway = 60;//当前时间减去60,把时间留点余地
            $token       = JWT::decode($jwt, KEY, ['HS256']); //HS256方式,这里要和签发的时候对应
        } catch (Exception $exception) {
            $res = array('code' => 302, 'msg' => $exception->getMessage());
            die(json_encode($res));
        }
    
    
        // 疑似窃取用户Token攻击行为:请求的客户端ip已经改变, 拒绝请求
        if ($token->aud !== $_SERVER['REMOTE_ADDR']) {
            $res['msg'] = "请求的客户端ip已经改变, 拒绝请求";
        }
    
        // token过了有效期, 但是在回旋时间内, 静默更新用户token
        if ($token->exp < time()) {
            $token        = (array)$token;
            $nowtime      = time();
            $token['iat'] = $nowtime; //签发时间
            $token['exp'] = $nowtime + 600; //过期时间-10min;
    
            $jwt = JWT::encode($token, KEY);
            header("Authorization:$jwt");
        }
    
        $res = array('code' => 200, 'msg' => 'success');
        die(json_encode($res));
    
    }
  • 相关阅读:
    理解javascript中的Array类型
    解决EF 4.0 中数据缓存机制
    vim学习之旅01-文本搜索并高亮显示
    Quartz.Net 学习之路02 初探Quartz.Net
    Quartz.Net 学习之路01 安装Quartz.Net
    EasyUI这个框架用了好久了,总结一下遇到的问题和解决方法
    记录剪切板
    如何将Unicode字符转换成简体字
    ass字幕转换成文本文件
    Change WORDS
  • 原文地址:https://www.cnblogs.com/jxl1996/p/10156871.html
Copyright © 2011-2022 走看看