如何在 hapi.js 上的路径上使用 hapi-auth-jwt2 身份验证?

Posted

技术标签:

【中文标题】如何在 hapi.js 上的路径上使用 hapi-auth-jwt2 身份验证?【英文标题】:How to use hapi-auth-jwt2 authentication on a path on hapi.js? 【发布时间】:2019-08-12 15:05:19 【问题描述】:

我在 hapi.js 中使用访问令牌时遇到问题。我无法理解如何使用该令牌进行身份验证。我正在关注这篇文章dwyl/hapi-auth-jwt2。我使用 mongodb 作为我的数据库。但是,在我像这样http://localhost:8000/restricted?token=mycreatedtoken 发送请求之前,我无法登录 auth: 'jwt' 页面。但是这样发送请求似乎不对。那么我该如何使用该令牌?我不必将其保存在本地存储或数据库中即可访问吗?这是我的代码:

app.js

 const jwt = require('jsonwebtoken');
 await server.register(require('hapi-auth-jwt2'));

    server.auth.strategy('jwt', 'jwt', 
        key: 'NeverShareYourSecret',
        validate: validate,
        verifyOptions:  algorithms: ['HS256'] 
      );
      server.auth.default('jwt');

验证函数:

const validate = async (decoded, req) => 
let user = await User.findOne( _id: decoded.id );
if (user) 
     req.user = user;
   return  isValid: true ;
   else 
   return  isValid: false ;
 
;

用于登录:

method: 'POST',
path: '/login',
config:  auth: false ,
handler: async function(req, h) 
  try 
    let  username, password  = req.payload;
    let student = await student.findOne(
      username
    );
    let validUser = student && (await bcrypt.compareSync(password,student.password));

    if (validUser) 
      let token = jwt.sign( id: user.id , 'mysecretkey');
      console.log('tpken'+token);
     // return h.view('welcome');
      return  token ;
     else 
      return boom.unauthorized('incorrect pass');
    
   

注册

method: 'POST',
path: '/student',
config:  auth: false ,
handler: async function(req, h) 
  try 
    let salt = bcrypt.genSaltSync(10);
    req.payload.password = bcrypt.hashSync(req.payload.password, salt);

    let student = new User(req.payload); 
    let result = await student.save();
    const  expiresIn  =  24  *  60  *  60;
    let token = jwt.sign( id: result.id , 'mysecretkey', expiresIn:  expiresIn
    );
    return token   ;     

   

此路径正在使用 jwt 令牌。

  
    method: 'GET', 
    path: '/register',
    config:  auth: 'jwt' ,
    handler: async (request, h) => 
        try 
              return h.view('student');
         catch(err)
            return h.response(err).code(500);
        
    
 

【问题讨论】:

【参考方案1】:

您能分享一下您的validate 功能吗?我了解您可以生成 JWT 令牌。为了使用该令牌来验证您的请求,您需要将该令牌与您的请求上的“授权”标头一起发送到您的服务器。

我在前端使用 react,这是我将 JWT 令牌发送到服务器的设置。

import axios, AxiosInstance from 'axios';

const createClient: () => AxiosInstance = () => 
    const options = 
        baseURL: process.env.REACT_APP_API_URL,
        responseType: 'json',        
        withCredentials: true,
        headers: 
            'X-Requested-With': 'XMLHttpRequest',
            'Authorization': ''
        ,
    ;

    const instance = axios.create(options);

    // Set the AUTH token for any request
    // ref: https://***.com/questions/43051291/attach-authorization-header-for-all-axios-requests
    instance.interceptors.request.use(function (config)         
        const token = localStorage.getItem("USER_JWT_TOKEN");
        config.headers.Authorization = token ? `Bearer $token` : '';     

        return config;
    );

    return instance;
;

export default createClient();

然后,当我使用此设置发出请求时,axios 会自动在我的所有请求中发送身份验证标头。

import apiClient from "./apiClient";

const results = await apiClient.get(`/users`);

有我从 chrome 的网络面板复制的请求的 curl 预览。

curl 'https://myserver.com/users' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/73.0.3683.75 Safari/537.36' -H 'Accept: application/json, text/plain, */*' -H 'Referer: https://myserver.com/' -H 'Origin: https://myserver.com' -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...... long JWT token string here' -H 'X-Requested-With: XMLHttpRequest' --compressed

【讨论】:

我添加了验证功能。而且我也愿意使用 react 作为前端,但我不确定如何发送它 您的验证功能没问题,但您应该在 else 语句中返回 isValid: false 。仅当您有一个向 api 后端发出请求的单页应用程序时,JWT 才合乎逻辑。当您尝试从服务器提取数据时,您需要在请求中添加授权标头。 假设这是我想要验证 <Route path="/add" exact component=AddStudent /> 的路由。在服务器上,我将/add 路径的身份验证设置为'jwt'。但在我提交发布按钮之前,页面没有显示 401 错误。但是单击后如果没有设置令牌,我会收到身份验证错误,但我想要的是,如果没有该令牌而不是页面的元素,则不应显示该页面

以上是关于如何在 hapi.js 上的路径上使用 hapi-auth-jwt2 身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用dropzone.js和hapi.js上传图像

如何在客户端上保存 JWT 令牌,在节点中使用 Hapi js。?

如何使用hapi.js读取已在浏览器中设置的cookie

Hapi js - 如何发送服务器请求进行基本身份验证?

将 Hapi.js 应用程序部署到 AWS EC2

hapi.js - 404 路由 VS 静态文件路由