【用户登陆鉴权PHP-JWT】JWT实战:使用axios+PHP实现登录认证

原文链接:https://www.cnblogs.com/helloweba/p/8616332.html

上一篇文中,我们学习了什么是JWT(Json Web Token),今天我们来结合实例给大家讲述JWT的实战应用,就是如何使用前端Axios与后端PHP实现用户登录鉴权认证的过程。

查看演示 下载源码

文中涉及的重要知识点有:

因此在阅读这边文章之前,请先了解以上知识点以及JWT的基本概念,这样你会很快理解我们这篇文章中的实例代码。

准备

在本站上篇文章《有关JWT(Json Web Token)的那些事》有介绍用户登录鉴权流程:

  • 用户使用用户名密码来请求服务器
  • 服务器进行验证用户的信息
  • 服务器通过验证发送给用户一个token
  • 客户端存储token,并在每次请求时附送上这个token值
  • 服务端验证token值,并返回数据

那么现在我们就按这个流程开始。

HTML

我们的HTML结构是这样的:一个登录表单,供用户输入用户名和密码,以及提交按钮;一个是登录成功后的显示信息。

复制代码

<div id="showpage" style="display: none">
  <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>
<div id="user" style="display: none"><p>欢迎<strong id="uname"></strong>,您已登录,<a href="javascript:;" id="logout">退出>></a></p></div>

复制代码

 

详细的代码,可以下载demo源码中查看,这里样式我们使用的是Bootstrap3的经典样式。

Javascript

前端Javascript异步请求,我们使用Axios库,当然你也可以使用jQuery的Ajax方法。

首先引入axios库:

1

<script src="https://cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>

  

按照流程,1.提交登录表单,发送用户名和密码到PHP后端,2.后端验证成功后,会发送一个token给前端,3.前端再拿这个token去请求需要用户权限访问,4.后端验证toen,鉴权,返回相应结果。下面的js代码实现了1,3两步。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

<script>

    document.querySelector('#sub-btn').onclick = function() {

    let username = document.querySelector('#username').value;

    let password = document.querySelector('#password').value;

    

    var params = new URLSearchParams();

    params.append('user', username);

    params.append('pass', password);

 

    axios.post(

        'user.php?action=login',

        params

    )

    .then((response) => {

        if (response.data.result === 'success') {

            // 本地存储token

            localStorage.setItem('jwt', response.data.jwt);

            // 把token加入header里

            axios.defaults.headers.common['X-token'] = response.data.jwt;

            axios.get('user.php').then(function(response) {

                if (response.data.result === 'success') {

                    document.querySelector('#showpage').style.display = 'none';

                    document.querySelector('#user').style.display = 'block';

                    document.querySelector('#uname').innerHTML = response.data.info.data.username;

                else {

                }

            });

        else {

            console.log(response.data.msg);

        }

    })

    .catch(function (error) {

        console.log(error);

    });

}

 

</script>

  

很显然,当登录成功后,立马使用本地存储token,然后把这个token放在请求头header里,再次去请求后端另一个用户信息接口,如果成功了就显示用户信息。

如果要退出登录,我们不需要再次去请求后端接口,直接前端清空本地存储就OK了。

1

2

3

4

5

document.querySelector('#logout').onclick = function() {

    localStorage.removeItem('jwt');

    document.querySelector('#showpage').style.display = 'block';

    document.querySelector('#user').style.display = 'none';

}

  

登录成功后,当我们刷新页面(再次请求需要登录后才能访问的页面),需要进行判断,判断本地存储中是否有token,如果有token,那就拿去给后端接口验证下token是否合法,如果没问题就显示用户相关信息,如果验证失败,那可能是token过去或者伪造的token等原因。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

let jwt =  localStorage.getItem('jwt');

 

if (jwt) {

    axios.defaults.headers.common['X-token'] = jwt;

    axios.get('user.php')

    .then(function (response) {

        if (response.data.result === 'success') {

            document.querySelector('#showpage').style.display = 'none';

            document.querySelector('#user').style.display = 'block';

            document.querySelector('#uname').innerHTML = response.data.info.data.username;

        else {

            document.querySelector('#showpage').style.display = 'block';

            console.log(response.data.msg);

        }

    })

    .catch(function (error) {

        console.log(error);

    });

else {

    document.querySelector('#showpage').style.display = 'block';

}

  

PHP

后端我们使用了一个专门的JWT库:php-jwt

使用composer安装php-jwt,接收到登录用户名和密码后,PHP验证用户名和密码是否正确(实际开发中应该结合数据库,从数据库里拿用户名和密码比对,本实例为了演示只做简单验证),如果用户名和密码准确无误,那么就签发token,在token中,我们可以定义token的签发者、过期时间等等,并返回给前端。注意在签发token时,我们需要定义一个密钥,这个密钥是一个私钥,实际应用中是保密的不可告诉别人。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

require 'vendor/autoload.php';

 

use \Firebase\JWT\JWT;

 

define('KEY''1gHuiop975cdashyex9Ud23ldsvm2Xq'); //密钥

 

$res['result'] = 'failed';

 

$action = isset($_GET['action']) ? $_GET['action'] : '';

 

if ($action == 'login') {

    if ($_SERVER['REQUEST_METHOD'] == 'POST') {

        $username = htmlentities($_POST['user']);

        $password = htmlentities($_POST['pass']);

 

        if ($username == 'demo' && $password == 'demo') { //用户名和密码正确,则签发tokon

            $nowtime = time();

            $token = [

                'iss' => 'http://www.helloweba.net', //签发者

                'aud' => 'http://www.helloweba.net', //jwt所面向的用户

                'iat' => $nowtime//签发时间

                'nbf' => $nowtime + 10, //在什么时间之后该jwt才可用

                'exp' => $nowtime + 600, //过期时间-10min

                'data' => [

                    'userid' => 1,

                    'username' => $username

                ]

            ];

            $jwt = JWT::encode($token, KEY);

            $res['result'] = 'success';

            $res['jwt'] = $jwt;

        else {

            $res['msg'] = '用户名或密码错误!';

        }

    }

    echo json_encode($res);

 

else {

    $jwt = isset($_SERVER['HTTP_X_TOKEN']) ? $_SERVER['HTTP_X_TOKEN'] : '';

    if (empty($jwt)) {

        $res['msg'] = 'You do not have permission to access.';

        echo json_encode($res);

        exit;

    }

 

    try {

        JWT::$leeway = 60;

        $decoded = JWT::decode($jwt, KEY, ['HS256']);

        $arr = (array)$decoded;

        if ($arr['exp'] < time()) {

            $res['msg'] = '请重新登录';

        else {

            $res['result'] = 'success';

            $res['info'] = $arr;

        }

    catch(Exception $e) {

        $res['msg'] = 'Token验证失败,请重新登录';

    }

 

    echo json_encode($res);

}

  

用户每次请求都要带上后端签发的token,后端获取请求中的token,PHP中使用$_SERVER['HTTP_X_TOKEN']就可以获取token值。这个X_TOKEN就是在我们前端的请求header头信息中。

然后PHP拿到这个token后,解密分析token值,返回给前端即可。

结束语

以上就是整个JWT的实战应用,我们可以看到,在用户鉴权的过程中并没有使用Session或者Cookie,服务端无需存储用户会话信息。只用了一个Token串,建立前后端的验证的数据传递,实现了有效的登录鉴权过程。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值