今天我们来学习一下如何通过jaguar_session_jwt进行用户的验证!
1.导包
在我们的pubspec.yaml
文件下添加下面代码
dependencies:
jaguar_session_jwt: ^2.2.1
然后执行pub get
命令
导入文件
import 'package:jaguar_session_jwt/jaguar_session_jwt.dart';
这里要注意,使用该包,需要配合jaguar_jwt
,jaguar_auth
这两个包使用
2,使用
-
1.对用户模型进行处理,让用户模型实现
PasswordUser
接口
class User implements PasswordUser{
@PrimaryKey()
String id;//id号
@Column(length: 20,isNullable: false)
String username;//用户名
@Column(length: 30,isNullable: false)
String password;//密码
@Column(isNullable: false)
bool isUse;//是否可用
String created;
@HasOne(AvatarBean)
Avatar avatar;//头像
@Column(isNullable: true)
String role;
@Column(length: 11,isNullable: true)
String phoneNumber;//电话号码
@Column(length: 30,isNullable: true)
String email;//邮箱
@Column(length: 200,isNullable: true)
String sign;//签名
@Column(isNullable: true)
String city;//城市
//表名
static const String tableName='_user';
//new
@override//授权身份验证
String get authorizationId => id;
//new
}
上面就是我今天用到的一个用户模型,内容还是很丰富的,可以注意到一个点,就是需要实现获取authorizationId
,我传入的是用户的id
,PasswordUser
还有一个password
需要实现,但是我已经定义好了,所以,不用再实现了,
-
2.定义一个用户提取器
该用户取样器,是当用户登陆时,会通过该取样器去校验是否正确
import 'dart:async';
import 'package:jaguar/jaguar.dart';
class DummyUserFetcher implements UserFetcher<User> {
final UserBean userBean;
const DummyUserFetcher(UserBean userBean,)
: userBean = userBean ;
//身份验证
Future<User> byAuthenticationId(Context ctx, String authenticationId) async =>
await userBean.findOneWhere(userBean.username.eq(authenticationId));
//授权书
Future<User> byAuthorizationId(Context ctx, String sessionId) async =>
await userBean.find(sessionId);
}
上面通过两个地方进行对用户的校验,一个是用户名,一个是用户id,用户id一般存在session里面,有小伙伴可能会对authenticationId
跟authorizationId
混淆,仔细看是两个东西来的,一个是认证id
,一个是授权id
ok,我们已经定义好了,下面是配置jwt
-
3.配置jwt
const JwtConfig config=const JwtConfig(key);
上面传入一个key,一般为27位秘钥,自己定义好就行,什么都可以,JwtConfig
还可以传入下面的字段
- String Issuer 发行人
- List<String> audience 受众
- Duration maxAge 过期时间,默认一天
像这样使用
const JwtConfig config=const JwtConfig(
key
,issuer: 'rhyme'
,audience: ['ben','jack']
,maxAge: Duration(days: 7));
-
4. 配置服务器
将上面已经配置好的jwt配置到服务器
main{
dbmg.init();
new Jaguar(sessionManager: JwtSession(config,io: SessionIoCookie()),)
..userFetchers[User]=DummyUserFetcher(new UserBean(dbmg.pgAdapter))
..add((reflect(UserController(dbmg.pgAdapter,cache))))
..serve(logRequests: true);
}
如果有看过我之前的文章应该知道UserBean
,pgAdapter
,cache
是什么吧,分别是User
的dao
类,数据库持有类
,缓存
,我们来重点讲一下JwtSession
吧
-
config
上面jwt配置 -
io
该参数可以传入SessionIoCookie()
令牌存在cookie,SessionIoAuthHeader()
令牌在授权头,SessionIoHeader
令牌在头(请求头与应答头) -
validationConfig
该参数为验证配置,用于验证令牌中的发行人与受众,所以,需要传入发行人与受众
详细说明一下io
这个参数吧
-
image.pngSessionIoCookie(cookieName: 'token',cookiePath: '/he')
,令牌自动放入到token
这个键对应的值中,/he
为路径,一般用于网页
-
image.pngSessionIoAuthHeader(scheme: 'rhyme')
,令牌放入到应答头中的authorization
,rhyme
拼接令牌
-
image.pngSessionIoHeader(name: 'token')
,令牌放入到应答头中对应传入的键中
5.登陆用户
下面我们来写一个登陆接口
@Post(path: '/login')
loginx(Context ctx) async{
//验证用户,并给予令牌
final User user=await FormAuth.authenticate<User>(ctx);
//返回用户信息
return Response.json((restful.ok_r()
..data=user).toMap(new UserSerializer()));
}
也可以这样写
@Post(path: '/login')
@Intercept(const [const FormAuth<User>()])
loginx(Context ctx) {
final User user=ctx.getVariable<User>();
return Response.json((restful.ok_r()
..data=user).toMap(new UserSerializer()));
}
FormAuth用于验证表单请求,编码题必须为application/x-www-form-urlencoded
FormAuth()构造方法可传入下面的参数
-
UserFetcher<UserModel> userFetcher
用户提取器,跟上面一样,默认使用服务器配置的 -
String authorizationIdKey
授权字段,默认为id
-
bool manageSession
如果为false
,则需要手动完成会话的创建,默认为true
-
Hasher hasher
用于密码校验,默认为NoHasher()
不需要校验
重点讲解下 Hasher hasher
,当服务器接收到用户名username
跟密码password
,如果密码是加密过的,就可以使用该参数,它支持的参数
-
NoHasher()
不需要进行校验 -
MD5Hasher(salt)
md5校验,salt
为盐值 -
Sha1Hasher(salt)
Sha1校验,salt
为盐值 -
Sha256Hasher(salt)
Sha256校验,salt
为盐值
同样的,还可以支持下面的请求
基本认证
@Post(path: '/login')
loginb(Context ctx) async => await BasicAuth.authenticate<User>(ctx);
上面的请求是将username
和password
经过:username:password拼接后通过base64加密放入到
请求头的authorization
对应的Basic
键中
json认证
@PostJson(path: '/login')
@Intercept(const [const JsonAuth<User>()])
User login(Context ctx) => ctx.getVariable<User>();
6.授权访问
当用户登陆后,我们需要登陆后才能操作
@Post(path: '/hello')
@Intercept(const [Authorizer<User>()])
hello(Context ctx){
return Response.json('hello');
}
我们这里如果是用户没有登陆,会提示用户去进行登陆,登陆过后,柴可以访问hello接口
7.退出登录
@Post(path: '/logout')
logout(Context ctx)async{
(await ctx.sessions).clear();
return Response.json('退出成功');
}
退出登录我们只要清理一下跟该客户端的sessions就可以退出了
ok,今天的内容就到这里,我们明天见!
如果想继续学习DartVM服务器开发,请关注我,学习更多骚操作!
网友评论