当前位置: 首页 > 科技观察

通俗易懂如何使用JWT加强API_0

时间:2023-03-21 22:01:26 科技观察

【.com快译】大家一定听说过JSONWebToken(JWT)吧?它是目前用于保护API的先进技术之一。与大多数安全概念和技术一样,在我们准备好使用它之前了解它的工作原理是必要且重要的。当然,JWT过于技术化和技术化的解释可能会让你感到困惑,甚至让你头疼。那么我试着用一种比较通俗易懂的方式给大家解释下JWT是如何对API进行强化的。API认证是不言而喻的。在复杂的网络环境中,我们需要对各种API资源进行访问限制。例如,我们不希望一个用户能够更改另一个用户的密码。然后,我们需要用户提交他们的ID和密码来保护和加固目标资源。换句话说:我们需要验证它们。在实际应用中,我们保护HTTPAPI的难点在于各种请求都是无状态的。即:API无法知道任何两个请求是否来自同一用户。可能有人会问:为什么我们不能要求用户在每次调用API时都提供ID和密码呢?答案是:因为会给用户带来很差的访问体验。JSONWebToken因此,我们需要的是:用户只需要提供一次信任凭证,在后续的请求中,服务器会以另一种方式识别用户。基于这样的想法,JSONWebToken应运而生。当然,如果你是喜欢学习的学生,可以通过链接:https://robmclarty.com/blog/what-is-a-json-web-token全面了解JSONWebToken的工作原理和深入的理解。让我们想象一下:如果你要入住酒店,“令牌”就是允许你进入自己房间的安全钥匙卡,以及酒店的其他设施,显然不是其他人的房间。并且退房时需要归还房卡,即:退出。Token结构通常,JSONWebToken是通过各种HTTP请求头发送的。如下图:Authorization:BearereyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U可以看出token就是“Authorization:Bearer”头信息的后半部分。上面的信息虽然比较乱,但是包含了以下几个部分:首先,token是由三个不同的字符串组成的,字符串之间用点号隔开。这三个字符串使用了base64编码,分别对应头部(header)、有效载荷(payload)和签名(signature),如下所示://HeadereyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9//PayloadeyJzdWIiOiIxMjM0NTY3ODkwIn0//SignaturedozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U注:base64是一种Themethodofconvertingthestringcanensurethattherewillbenoproblemsintheprocessoftransmittingthe网络上的字符串。由于它不是一种加密方法,任何人都可以轻松地对其进行解码以查看原始数据。下面,我们对上面的字符串进行解码,以更好地理解JWT的结构。Head通过解码token的header,我们可以得到如下元信息。由于对我们理解整体的工作原理帮助不大,这里就不详细解释了。{"alg":"HS256","typ":"JWT"}Payload有效载荷中的内容要多得多。您可以使用它来包含您需要传递的任何数据。此处,由于令牌的目的是验证对API的访问,因此仅包括用户ID。{"userId":"1234567890"}值得注意的是:负载不安全。任何人都可以解码令牌以准确查看有效负载中的内容。因此,我们通常只包含ID,而不包含用户电子邮件内容等敏感识别信息。虽然此有效负载为API提供了识别用户所需的所有信息,但它不提供特定的身份验证方法。毕竟有了这些信息,黑客就可以轻松找到用户的ID,伪造token。因此,我们还需要有一个签名,它是令牌认证链中非常关键的一环。哈希算法在我们开始解释签名如何工作之前,我们需要了解什么是哈希算法。首先,它是一个函数,可用于将目标字符串转换为另一个称为散列值(hash)的新字符串。例如,我们对字符串“Hello,world.”进行哈希运算,经过SHA256哈希算法后可以得到如下输出:4ae7c3b6ac0beff671efa8cf57386151c06e58ca53a78d83f36107316cec125f注意:哈希算法有很多种,JWT常用的是SHA256。散列的一个重要特性是我们不能使用散列算法通过散列值来识别原始字符串。也就是说,我们无法直接计算或推导出原始字符串“Hello,world”。与上述哈希值。理论上,基于哈希的复杂度,猜出原始字符串是完全不可行的。JWT签名现在,让我们看一下JWT令牌结构的第三部分:签名。其实这部分是需要计算的。HMACSHA256(base64UrlEncode(header)+"."+base64UrlEncode(payload),"secretstring");我们来详细分析一下上面的代码:首先,HMACSHA256是哈希函数的名称,它使用了两个参数:希腊字符串和key(secret)。其次,需要散列的字符串是base64编码的标头和有效负载。第三,密钥是一串只有服务器知道的任意数据。Q:为什么签名的hash中要加header和payload?答:这确保签名对于该特定令牌是唯一的。问:什么是钥匙?A:让我们从如何伪造令牌来回答这个问题。我们之前说过,黑客无法从输出值中推断出散列的输入信息。但是,由于签名中包含了header和payload,而且这些都是公开信息,如果黑客知道哈希算法(通常在header中指定),那么他就可以生成相同的hash值。可见,如果服务器有一个非公钥,并将其包含在散列过程中,就可以防止黑客伪造和生成带有散列值的token。同时,由于哈希值“覆盖”了各种原始信息,也保证了密钥不被黑客发现。注意:将私有数据添加到哈希的过程(称为加盐)使得破解令牌几乎不可能。认证流程至此,你一定已经了解了token的创建流程。那么,我们如何使用它来对API的用户进行身份验证呢?登录当用户登录时,将生成令牌并将其与用户模型一起存储在数据库中。logincontrol.js:if(passwordCorrect){user.token=generateToken(user.id);user.save();}然后作为对登录请求的响应,将令牌添加到授权标头。logincontrol.js:if(passwordCorrect){user.token=generateToken(user.id);user.save();res.headers("authorization",`Bearer${token}`).send();}认证请求有了令牌,用户现在可以将其添加到各种后续的真实性请求中。服务器收到添加了身份信息的token请求后,会进行如下操作:对token进行解码,从payload中提取ID。使用此ID,在数据库中查找用户的信息。将请求令牌与存储的令牌与用户模型进行比较。如果匹配,则该用户被视为“合法”。authMiddleware.js:consttoken=req.header.token;constpayload=decodeToken(token);constuser=User.findById(payload.id);if(user.token=token){//Authorized}else{//Unauthorized}注销如果用户要求注销,系统只需删除当前添加到用户模型的令牌。由于用户手中的token及时过期,如果需要重新登录,应该重新生成一个新的token。logoutcontrol.js:user.token=null;user.save();小结通过以上一步一步的分析,希望你对如何使用JSONWebToken来加强API已经有了一个基本的概念。当然,这个主题涵盖的内容远不止于此。有兴趣的可以通过以下链接阅读:Jwt.io-https://jwt.io/WhatisJSONWebToken?-https://robmclarty.com/blog/what-is-a-json-web-token【翻译稿件,合作网站转载请注明原译者及出处.com】