当前位置: 首页 > 知识库问答 >
问题:

基于令牌的身份验证中的会话

姬英武
2023-03-14

我正在PHP Lumen中构建一个应用程序,它在登录时返回令牌。我不知道如何继续。

我应该如何使用这些令牌维护会话?

具体来说,如果我使用reactjs或vanilla HTML/CSS/jQuery,我如何在客户端存储令牌,并在我为web应用程序的安全部分发出的每个请求中发送它们?

共有3个答案

阎晋
2023-03-14

目前正在使用 API 的 lummen 开发相同类型的应用程序。以下 3 个步骤使用 JWT 在 Lumen 中进行基于令牌的身份验证:

1.创建令牌并在登录成功后返回

public function login(Request $request) {
    $token = $this->jwt->attempt(['user_name' => $data['user_name'], 'password' => $data['password']]); //$token = $this->jwt->attempt($data); 
    if (!$token) {
        $response = array('success' => false, 'data' => null, 'detail' => array('message' => Messages::MSG_INVALID_USER, 'error' => array(Messages::MSG_INVALID_USER)));
        return response()->json($response);
    } else {
        $user = \Auth::setToken($token)->user();
        $data = array('token' => $token,'user_id' => $user->id);
        $response = array('success' => true, 'data' => $data, 'detail' => array('message' => Messages::MSG_SUCCESS, 'error' => null));
        return response()->json($response);
    }
}

2. 定义令牌验证的中间件

public function handle($request, Closure $next, $guard = null) {
    try {
        $token = $request->header('X-TOKEN');
        $user_id = $request->header('X-USER');
        $user = \Auth::setToken($token)->user();
        if ($user && $user->id == $user_id) {
            return $next($request);
        } else {
            $response = array('success' => false, 'data' => null, 'detail' => array('message' => Messages::MSG_ERR_INVALID_TOKEN, 'error' => Messages::MSG_ERR_INVALID_TOKEN));
            return response()->json($response);
        }
    } catch (Exception $ex) {
        $response = array('success' => false, 'data' => null, 'detail' => array('message' => Messages::MSG_ERROR_500, 'error' => array($ex)));
        return response()->json($response);
    }
}

3. 将令牌存储在本地存储或 cookie 中

localStorage.setItem("Token", JSON.stringify(TokenData));
TokenData = JSON.parse(localStorage.getItem("Token"));

$.cookie('Token', JSON.stringify(TokenData), {expires: 1, path: '/'});
TokenData = JSON.parse($.cookie("Token"));

4. 在标头中为每个请求发送令牌

带有自定义标题的请求

$.ajax({
    url: 'foo/bar',
    headers: { 'X-TOKEN': TokenData.Token ,'X-USER': TokenData.UserId}
});

每个请求的标题

$.ajaxSetup({
        headers: { 'X-TOKEN': TokenData.Token ,'X-USER': TokenData.UserId}
    });

希望有帮助。

注意:在从localstoragecookies读取数据时,添加一些检查和数据验证。

景嘉实
2023-03-14

让我们假设你想用。

  1. 反应JS
  2. 带有PHP的REST API
  3. 使用JWT

在构建REST API时,必须忘记会话。

REST API应该是无状态的,所以它们不能依赖于会话,它们必须只使用客户端给定的数据来处理请求。

客户端想要做的只是交换一些< code >用户名

这是一个示例 HTTP 请求

POST /api/v1/authentication HTTP/1.1
Host: localhost
Content-Type: application/json
{
    "username": "foo",
    "password": "bar"
}

答案是:

{
    "token": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

我们的API将如何处理身份验证请求?

> < li>

它将检查用户名为< code>foo的用户是否

它将生成JWT(Json Web Token)

它将返回包含JWT的响应

这是一些超级简单的认证方法,只是举个例子。

public function authAction()
{
  /** Get your payload somehow */
  $request = $_POST;

  //Validate if username & password are given/

  $user = $this->model->auth($username, $password);

  if(!$user) {
    //throw error for not valid credentials
  }

  $jwt = $this->jwt->create($user);

  //return response with $jwt
}

正如你所看到的,它们没有会话集或任何东西。

我们的客户将如何处理响应?

客户端可以使用诸如超级代理之类的包来处理请求

  let data = {
    username: email,
    password: password
  };

  request
    .post('/api/v1/authentication')
    .set('Content-Type', 'application/json')
    .send(data)
    .end(function (error, response) {
      //response.body.token
    });

您可以使用一些 3RD PT 包来生成和验证 JWT,而不是自己编写。

看看这个包,你可以看到它是如何完成的。

请记住,始终创建强大的签名。我建议使用RSA密钥

我不是在宣传或支持这个项目,只是发现在这里分享它很有用。我从未使用过它,我在我的NodeJS项目中使用了类似的东西。

正如您已经知道的< code>localStorage有两种方法

  1. 它们更安全一些。
  2. 可以在不实现某些自定义逻辑的情况下设置到期日期。
  3. 较旧的浏览器
  4. 支持(非常旧的浏览器,所以它并不那么重要)。

但这完全取决于你。

从现在起,对服务器的每个请求都必须包含您的JWT。

在您的REST API中,您必须编写一个方法来验证JWT并将其交换给用户对象。

请求示例:

  let jwt = ...; //GET IT FROM LOCALSTORAGE OR COOKIE

  request
    .get('/api/v1/posts')
    .set('Content-Type', 'application/json')
    .set('Authorization', jwt)
    .end(function (error, response) {

    });

API将如何处理此请求

public function postsAction()
{
  $jwt = $this->headers->get('Authorization');

  if(!$this->jwt->validate($jwt)) {
    //throw unauthorized error
  }

  $user = $this->model->exchangeJWT($jwt);

  //Your logic here
}

如果您使用cookie来保存您的JWT,请小心设置过期日期。

cookie过期日期必须等于JWT过期日期。

督辉
2023-03-14

我通常做的是将令牌保存在本地存储中,这样即使用户离开站点,我也可以持久保存令牌。

localStorage.setItem('app-token', theTokenFromServer);

每次用户加载页面时,我要做的第一件事就是查找令牌的存在。

token = localStorage.getItem('app-token');

如果使用反应,我会将令牌保持在全局状态(例如使用redux):

function loadAppToken(token) {
  return {
    type: 'LOAD_TOKEN',
    payload: { token },
  };
}

使用vanilla javascript,我会将其保留在我的连接实用程序中。可能如下所示:

const token = localStorage.getItem('app-token');

export function request(config) {
   const { url, ...others } = config;

   return fetch(url, {
     ...others,
     credentials: 'include',
     headers: {
       'Authorization': `Bearer ${token}`
     },
   });
}

我在react应用程序中仍然有一个fetch实用程序,类似于前面的代码,但是我会在选项中发送令牌,通过在redux中间件中为每个请求获取令牌。

 类似资料:
  • 问题内容: 我正在PHP Lumen中构建一个应用程序,该应用程序在登录时会返回令牌。我不知道如何继续进行。 我应该如何使用这些令牌维护会话? 具体来说,如果我使用reactjs或原始HTML / CSS / jQuery,如何将令牌存储在客户端,并在我为Web应用程序的安全部分提出的每个请求中发送令牌? 问题答案: 我通常要做的是将令牌保留在本地存储中,这样即使用户离开站点,我也可以保留令牌。

  • 问题内容: 我有一个REST API,我正在使用Spring Security基本授权进行身份验证,客户端会为每个请求发送用户名和密码。现在,我想实现基于令牌的身份验证,当用户最初通过身份验证时,我将在响应标头中发送令牌。对于进一步的请求,客户端可以在令牌中包含该令牌,该令牌将用于对资源进行用户身份验证。我有两个身份验证提供程序tokenAuthenticationProvider和daoAuth

  • 在daoAuthenticationProvider中,我设置了自定义userDetailsService并通过从数据库中获取用户登录详细信息对其进行身份验证(只要使用授权传递用户名和密码就可以正常工作:basic bgllqxbpvxnlcjogn21wxidmqjrdturtr04pag==作为头) 但是当我使用X-AUTH-TOKEN(即constants.auth_header_name)

  • 我正在使用ASP.NET核心应用程序。我正在尝试实现基于令牌的身份验证,但无法确定如何使用新的安全系统。我查看了一些示例,但它们对我没有太大帮助,它们使用的是cookie身份验证或外部身份验证(GitHub、Microsoft、Twitter)。 我的场景是:angularjs应用程序应该请求url,传递用户名和密码。WebApi应该授权user并返回,angularjs应用程序将在以下请求中使用

  • 我读了一些关于“JWT vs Cookie”的帖子,但它们只会让我更加困惑…… > 我想澄清一下,当人们谈论“基于令牌的身份验证与cookie”时,这里的cookie仅指会话cookie?我的理解是,cookie就像一个介质,它可以用来实现基于令牌的身份验证(在客户端存储可以识别登录用户的东西)或者基于会话的身份验证(在客户端存储与服务器端会话信息匹配的常量) 为什么我们需要JSON web令牌?

  • null 我的自定义rest筛选器: 上面的内容实际上会导致应用程序启动时出现一个错误:有人能告诉我如何最好地执行此操作吗?pre_auth筛选器是执行此操作的最好方法吗? 编辑 使用Spring-security实现解决方案 希望它能帮助其他人…