美文网首页Java服务器端编程DartVM服务器开发
DartVM服务器开发(第十六天)--Jaguar使用JWT

DartVM服务器开发(第十六天)--Jaguar使用JWT

作者: rhyme_lph | 来源:发表于2018-09-05 22:24 被阅读43次

    今天我们来学习一下jaguar如何使用JWT!

    1.JWT是什么?

    学习如何使用之前,我们来了解一下什么是JWT

    JWT(Json Web Token)Json网络令牌,是基于Json的开放标准,是一个用私钥编码和签名的JSON数据,由于它已签名,因此无法篡改数据。在存在私钥的情况下,可以跨多个服务器验证数据(用于完整性和真实性)。
    JWT令牌有三部分:

    • Header
      包含用于对令牌签名的算法,用于声明类型typ和加密算法alg,该内容使用base64加密
    {
        "typ": "JWT",
        "alg": "HS256"
    }
    
    • Body
      主要为json数据,该数据经过Base64URl编码,包含声明
      • 标准声明(建议使用)
        iss: jwt签发者
        sub: jwt所面向的用户
        aud: 接收jwt的一方
        exp: jwt的过期时间,这个过期时间必须要大于签发时间
        nbf: 定义在什么时间之前,该jwt都是不可用的.
        iat: jwt的签发时间
        jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
      • 公有声明
        该部分可添加任何信息
      • 私有声明
        客户端与服务端共同定义的声明
    • Signature
      根据算法,签名包含使用私钥签名的正文签名
      =header.alg(base64UrlEncode(header) + "." + base64UrlEncode(body))*私钥

    ok,我们了解了什么是JWT, 下面我们开始使用

    2.Jaguar使用JWT

    • 添加依赖

    pubspec.yaml文件下添加下面内容

    dependencies:
    #....
      jaguar_jwt: ^2.1.5
    

    然后运行pub get

    成功.png
    可以看到,没有任何问题
    • 导入包

    我们在main.dart文件下面导入包

    import 'package:jaguar_jwt/jaguar_jwt.dart';
    
    • 使用

    首先我们来声明一个私钥key

    final key ='rhymelph123flutterdartvmser';
    

    然后添加body

    final JwtClaim jwtClaim=new JwtClaim(
                subject: 'rhyme',//发明者
                issuer: 'jaguar',//发行的令牌
                issuedAt: DateTime(2018,9,4,11,11),//发行的时间
                expiry: DateTime(2018,9,6),//令牌到期时间
                jwtId: '1',//唯一id
                audience: ['ben','jack'],//令牌受众者
                payload: { "data":"数据",},
              );
    

    根据bodykey生成token,这里的大部分处理,jaguar_jwt都帮你处理好了

    String token = issueJwtHS256(jwtClaim, key);
    

    通过tokenkey获取JwtClaim

          final jwtClaim=verifyJwtHS256Signature(token, key);
    

    3. 实战

    下面,我会通过登陆功能使用JWT
    我们先定义两个接口,分别都使用post方式进行请求

    • /api/User/Login 登陆,传入账号和密码
    • /api/User/Info 获取用户信息,根据传入的token
      好了,接口有了,我们定义一个工具类,专门返回json数据
    import 'dart:convert';
    
    ApiJson apiJson = new ApiJson();
    
    class ApiJson {
    
      String success() =>
          json.encode(new Api()
            ..code = 0
            ..msg = 'success'
            ..data = null,);
    
      Api successA() =>
          new Api()
            ..code = 0
            ..msg = 'success'
            ..data = null;
    
    
      String successResult(Object data) =>
          json.encode(new Api()
            ..code = 0
            ..msg = 'success'
            ..data = data,);
    
      Api successResultA(Object data) =>
          new Api()
            ..code = 0
            ..msg = 'success'
            ..data = data;
    
    
      String error() =>
          json.encode(new Api()
            ..code = -1
            ..msg = '未知错误'
            ..data = null);
    
      Api errorA() =>
          new Api()
            ..code = -1
            ..msg = '未知错误'
            ..data = null;
    
      String errorMsg(int code, String msg) =>
          json.encode(new Api()
            ..code = code
            ..msg = msg
            ..data = null);
    
      Api errorMsgA(int code, String msg) =>
          new Api()
            ..code = code
            ..msg = msg
            ..data = null;
    }
    
    class Api<T> {
      int code;
      String msg;
      T data;
    
      Map toMap() =>
          {
            "code": code,
            "msg": msg,
            "data": data,
          };
    }
    

    登陆接口

    ..post('/api/User/Login', (ctx) async{
          Map<String,String> params=await ctx.bodyAsUrlEncodedForm();
          String username=params['username'];
          String password=params['password'];
          if(username.isEmpty||password.isEmpty){
          //用户名或密码为空
            return Response.json(apiJson.errorMsgA(-1, '用户名或密码为空!').toMap());
          }else{
          //在数据库中查询用户名
            User user=await userBean.findOneWhere(userBean.username.eq(username));
            if(user==null || user.password!=password){
          //用户名或密码不正确
              return Response.json(apiJson.errorMsgA(-2, '用户名或密码不正确!').toMap());
            }else{
    //正确,返回一个token信息
              final JwtClaim jwtClaim=new JwtClaim(
                subject: 'rhyme',//发明者
                issuer: 'jaguar',//发行的令牌
                issuedAt: DateTime(2018,9,4,11,11),//发行的时间,这里的时间应该是当前时间
                expiry: DateTime(2018,9,6),//令牌到期时间,该时间应该在发行时间加一两天
                jwtId: '1',//唯一id
                audience: ['ben','jack'],//令牌受众者
                payload: user.toMap(),
              );
    
              String token=issueJwtHS256(jwtClaim, key);
              return Response.json(apiJson.successResultA(token).toMap());
            }
          }
        })
    

    获取用户信息接口

    ..post('/api/User/Info', (ctx) async{
          Map<String,String> params=await ctx.bodyAsUrlEncodedForm();
          String token=params['token'];
          final jwtClaim=verifyJwtHS256Signature(token, key);
          return Response.json(jwtClaim.payload);
        })
    

    下面我们来请求一下吧!


    登陆.png
    请求用户信息.png

    可以看到,我们成功的使用了JWT,好了,今天的内容就到这里了,我们明天见!

    如果想继续学习DartVM服务器开发,请关注我,学习更多骚操作!

    下一篇:DartVM服务器开发(第十七天)--Jaguar_websocket结合Flutter搭建简单聊天室

    相关文章

      网友评论

        本文标题:DartVM服务器开发(第十六天)--Jaguar使用JWT

        本文链接:https://www.haomeiwen.com/subject/beezwftx.html