iOS开发 - 基于Token的身份验证-JWT
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发 - 基于Token的身份验证-JWT相关的知识,希望对你有一定的参考价值。
参考技术A JWT就是一个字符串,经过加密处理与校验处理的字符串,形式为: A.B.Cheader格式为
它就是一个json串,两个字段是必须的,不能多也不能少。alg字段指定了生成C的算法,默认值是HS256
将header用Base64Url编码,得到A
通常,JWT库中,可以把A部分固定写死,用户最多指定一个alg的取值
将上面的JSON对象进行Base64Url编码,得到B
将A.B使用RS256加密(其实是用header中指定的算法),当然加密过程中还需要密钥(自行指定的一个字符串)。
加密得到C,学名signature,其实就是一个字符串。作用类似于CRC校验,保证加密没有问题。
现在A.B.C就是生成的token了。
可以使用
JWT调试
Objective-C JWT https://github.com/yourkarma/JWT
我们使用的是RSA256
文档
生成环境是在mac系统下,使用openssl进行生成,首先打开终端,按下面这些步骤依次来做:打开openssl
1.生成模长为1024bit的私钥文件 private_key.pem
注意:这一步会提示输入国家、省份、mail等信息,可以根据实际情况填写,我测试了不填写的情况,会报错.这里会提示输入密码
注意:这一步会提示给私钥文件设置密码,直接输入想要设置密码即可,然后敲回车,然后再验证刚才设置的密码,再次输入密码,然后敲回车,完毕!
在解密时,private_key.p12文件需要和这里设置的密码配合使用,因此需要牢记此密码.
把.der和.p12格式的秘钥文件导入工程中,把私钥和秘钥发给后台,使用一套私钥秘钥,就完成了JWT token的生成!
使用JWT 进行基于 Token 的身份验证方法
一般weby应用服务都使用有状态的session来存储用户状态以便认证有权限的用户进行的操作。但服务器在做横向扩展时,这种有状态的session解决方案就受到了限制。所以在一些通常的大型web应用场景越来越多在采用没有状态的token来进行用户签权处理。需要把Web应用做成无状态的,即服务器端无状态,就是说服务器端不会存储像会话这种东西,而是每次请求时access_token进行资源访问。这里我们将使用 JWT 1,基于散列的消息认证码,使用一个密钥和一个消息作为输入,生成它们的消息摘要。该密钥只有服务端知道。访问时使用该消息摘要进行传播,服务端然后对该消息摘要进行验证。
认证步骤
1.客户端第一次使用用户名密码访问认证服务器,服务器验证用户名和密码,认证成功,使用用户密钥生成JWT并返回
2.之后每次请求客户端带上JWT
3.服务器对JWT进行验证
首先使用JWTUtil类 来完成生成token和验证token的工作
public class JwtUtil {
private static String SECRET = "com.mozi.shop.secret";
private static String ISSUER = "MoziShop";
/**
* 生成token
*
* @param claims
* @return
*/
public static String createToken(Map<String, String> claims) throws Exception {
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTCreator.Builder builder = JWT.create()
.withIssuer(ISSUER)
//设置过期时间为2小时
.withExpiresAt(DateUtils.addHours(new Date(), 2));
claims.forEach(builder::withClaim);
return builder.sign(algorithm);
} catch (Exception e) {
throw new Exception("生成token失败");
}
}
/**
* 验证jwt,并返回数据
*/
public static Map<String, String> verifyToken(String token) throws Exception {
Algorithm algorithm;
Map<String, Claim> map;
try {
Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
return true;*/
///
algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm).withIssuer(ISSUER).build();
//JWTVerifier verifier = JWT.require(algorithm).build();
DecodedJWT jwt = verifier.verify(token);
map = jwt.getClaims();
} catch (Exception e) {
throw new Exception("鉴权失败");
}
Map<String, String> resultMap = new HashMap<>(map.size());
map.forEach((k, v) -> resultMap.put(k, v.asString()));
return resultMap;
}
}
在用户进行正常登录操作时返回客户端一个和失效时间的token
/**
* 登录页面
*/
public void index(){
String username = getPara("username");
String password = getPara("password");
// System.out.println("LOGIN USERNAME:"+username);
if(StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)){
Member member = new Member().dao().findByUsername(username);
if(member == null){
//setAttr("feedback", Feedback.error("用户不存在"));
setAttr("feedback", "用户不存在");
//System.out.println("LOGIN USERNAME 用户不存在:"+username);
render("/templates/"+getTheme()+"/"+getDevice()+"/login.html");
return;
}else if(!DigestUtils.md5Hex(password).equals(member.getPassword())){
//setAttr("feedback", Feedback.error("用户名密码错误"));
setAttr("feedback", "用户名密码错误");
render("/templates/"+getTheme()+"/"+getDevice()+"/login.html");
return;
}else{
/////jwt start///////////////////////////////////////////
Map<String, String> map = new HashMap<>();
map.put("id", (member.getId()).toString());
map.put("name", member.getUsername());
map.put("openid", member.getWeixinOpenId());
String token = null;
try {
token = JwtUtil.createToken(map);
}catch (Exception e) {
}
this.getResponse().setHeader("token", token);
/////jwt end////////////////////////////////////////////
redirect("/");
return;
}
}else{
System.out.println("nousername and pwd!!!!!!!!!!!!!!!");
render("/templates/"+getTheme()+"/"+getDevice()+"/login.html");
}
}
然后在需要授权的访问中鉴定用户携带的token,验证有效就进行操作
String token = getRequest().getHeader("token");
try {
Map<String, String> res = JwtUtil.verifyToken(token);
System.out.println(JSON.toJSONString(res));
}catch (Exception e) {
System.out.println(e);
}
以上是关于iOS开发 - 基于Token的身份验证-JWT的主要内容,如果未能解决你的问题,请参考以下文章