0
点赞
收藏
分享

微信扫一扫

app侧登录流程:打开app,如果 token不过期,就使用最近一次登录的token进行接口请求


I 前置知识

1.1 分布式系统下的session

app侧登录流程:打开app,如果 token不过期,就使用最近一次登录的token进行接口请求_数据库

session: 一种保存key-value的机制 key:

  1. sessionID
  2. token (配合签名一起使用)


app侧登录流程:打开app,如果 token不过期,就使用最近一次登录的token进行接口请求_iOS_02

1.2 服务端侧的登录处理

  1. openid去和数据库里的数据匹配(采用微信授权登录)
  2. 设置token至redis
  3. 设置token至cookie

1.3 app侧需求

  1. 冷启动app时,若token不过期,就使用最近一次登录的token进行数据请求
  2. 优化token的存储方式:

之前只是存储在内存,只要杀死app,重新打开就要求重新登录。现在改为将token信息存储到本地数据库,每次打开app使用最近一次登录获得的token。

II app侧登录流程

2.1 开发步骤

  • I、保存token到UserInfoModel 对象中
  • II、再次打开app的时候获取token
  • III、退出登录或者(token)失效进行信息信息清除
  • IV、在登录界面的viewDidLoad 进行判断是否直接进入首页
  • V : token存储区分正式环境和测试环境(UserInfoModel 对象新增一个当前token的域名属性currentHost,用于查询判断) 5.1) 更换表名 5.2)UserInfoModel新增字段currentHost, 5.3)查询token新增条件currentHost 5.4) 存储token新增字段currentHost

2.2 token信息存储注意事项

登录账号得到的token信息。最好不要作为一个独立的单利对象存储;而是将它作为单例对象的属性userInfo,这样便于切换账号存储token和其他账号信息

  • 如果之前是使用独立的单利对象UserInfoModel ,为了兼容代码可以这么做

/**
登录账号得到的token信息。最好不要作为一个独立的单利对象存储;而是将它作为单例对象的属性userInfo,便于切换账号存储token和其他账号信息。
*/
+ (instancetype)shareUserInfoModel{

return

​​使用线程安全模式来创建共享实例,并使用条件编译#if进行ARC、MRC的适配​​

​​kunnan.blog.csdn.net/article/det…​​

2.3 整体思路

保存和清除token

  • 使用BGFMDB 进保存最近一次登录的token

pod 'BGFMDB', '~> 2.0.13'  #2.0.9

  • 切换账号的时候更换token
  • 请求接口发现token 失效的时候,回到登录界面

III 核心实现

3.1 Session 对象的创建

使用HSSingleton工具类实现单例,并将包含登陆token及其他有状态相关字段的userInfo对象作为单例对象的属性

HSSingletonH(Session);
HSSingletonM(Session);

+ (void)SaveUserInfo:(UserInfoModel *)userInfo{

QCTSession.shareQCTSession.userInfo = userInfo;
}

存储token信息

#pragma

+ (void)saveModelWithModel:(UserInfoModel*)userModel{
[self emptySeeionLocal];


userModel.bg_tableName = QCTUserInfoModelTableName;

BOOL isSave = [userModel bg_save];// 保存方法
if (isSave) {
NSLog(@"token保存成功:%@",userModel.mj_keyValues);


}else{
NSLog(@"token保存失败:%@",userModel.mj_keyValues);


}


}

+(void)emptySeeionLocal{


NSMutableArray *tmparr = [NSMutableArray arrayWithArray:[[self class] bg_find:QCTUserInfoModelTableName where:nil] ];


// 先删除

for (UserInfoModel *loginModel in tmparr) {
NSString *where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"bg_id"),bg_sqlValue(loginModel.bg_id)];


BOOL isDelete = [UserInfoModel bg_delete:[NSString stringWithFormat:@"%@",QCTUserInfoModelTableName] where:where];
NSLog(@"删除重复数据%@:%@",isDelete?@"成功":@"失败",loginModel.mj_keyValues);
// break;
//

获取token信息

+ (instancetype)getmodel4LoginSeesion{


NSMutableArray *tmparr = [NSMutableArray arrayWithArray:[[self class] bg_find:QCTUserInfoModelTableName where:nil] ];




if(tmparr.count>0 ){
UserInfoModel *userModel = tmparr.firstObject;
// QCTSession.shareQCTSession.userInfo = userModel;

[ QCTSession SaveUserInfo:userModel];

NSLog(@"获取的token 信息%@",userModel);


return tmparr.firstObject;

}

NSLog(@"获取的token userModel.shareUserInfoModel %@",UserInfoModel.shareUserInfoModel);


//

return

3.2 保存token到UserInfoModel 对象中的时机

  • 登录的时候

[ Session SaveUserInfo:userModel];

[UserInfoModel saveModelWithModel:userModel];

  • app 退出的时候:applicationWillTerminate 、applicationWillResignActive

- (void)applicationWillTerminate:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.

3.3 再次打开app的时候获取token

#pragma

- (void)initInfo{

QCTSession.shareQCTSession.tmpUserInfoModel = nil;

[UserInfoModel getmodel4LoginSeesion];// 获取会话
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self

3.4 退出登录或者(token)失效进行信息信息清除

  • 在 application :didFinishLaunchingWithOptions: 方法进行监听

weak __typeof__(self) weakSelf = self;

[[[NSNotificationCenter defaultCenter] rac_addObserverForName:kExitlogshowLoginViewNotification object:nil] subscribeNext:^(NSNotification *notification) {


NSString *tmp = @"";

if(notification.object){

tmp = notification.object;

[weakSelf.window showHUDMessage:tmp afterBlock:^(id _Nonnull sender) {
[weakSelf setupExitlogout];

}];





}else{
// tmp = @"";

  • 退出登录(token过期)的处理

/**
1、移除极光的别名
2、初始化一些信息
3、清除账户信息缓存(本地数据库和内存中的token信息)

*/
- (void)setupExitlogout
{
[JPUSHService setTags:nil alias:@"" callbackSelector:@selector(tagsAliasCallback:tags:alias:) object:self];

[UserInfoModel cleanInfoWithblock:^(id sender) {

//3、登录
UserInfoModel.shareUserInfoModel.token = nil;

AppDelegate *appDelegate = (AppDelegate *)[[UIApplication

  • 清除本地数据库的token

+ (void)cleanInfoWithblock:(void (^)(id sender))block{


[[UserInfoModel shareUserInfoModel] cleanInfo];




if(block){
block(nil);
}


}
- (void)cleanInfo{
#pragma
[[self class] emptySeeionLocal];//

[self setToken:nil];

_CurrentSysUser = nil;
// _
[QCTSession shareQCTSession].tmpUserInfoModel = nil;


}

3.5 在登录界面的viewDidLoad 进行判断是否直接进入首页

  • viewDidLoad 早createSubView的时候进行判断,是否直接进入首页

if(UserInfoModel.shareUserInfoModel.isLoginByToken){


[[self class] jumpHome];


return;
}

  • 判断是否有token

/**
判断是否有token
*/
- (BOOL)isLoginByToken{


if(![NSStringQCTtoll isBlankString:UserInfoModel.shareUserInfoModel.token]){


return YES;
}

return NO;


}

3.6 token存储区分正式环境和测试环境

  • UserInfoModel 对象新增一个当前token的域名属性currentHost,用于查询判断环境
  • BGFMDB如果新增字段,就需要更换一下表名

#warning
2021-01-29 17:16:10.418453+0800 Housekeeper[15013:1071895] [logging] table QCTUserInfoModelTableName0401 has no column named BG_IsreqGetCurrentSysUsering in "insert into QCTUserInfoModelTableName0401(BG_currentHost,BG_BearerToken,BG_token,BG_DictionariesEnum,BG_DictionariesEnumDictionary,BG_loginCode,BG_isGotoChangePassword,BG_HaveDefaultLevel,BG_bg_updateTime,BG_loginMessage,BG_IsreqGetCurrentSysUsering,BG_IsTobacco,BG_bg_createTime,BG_MsgsourceStr,BG_isShowBindingMobileNote) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"

  • 根据域名进行存取token的

app侧登录流程:打开app,如果 token不过期,就使用最近一次登录的token进行接口请求_字段_03

NSString*  where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"currentHost"),bg_sqlValue(currentHost)];
NSMutableArray *tmparr = [NSMutableArray arrayWithArray:[[self class] bg_find:QCTUserInfoModelTableName where:where] ];

存储token信息

+ (void)saveModelWithModel:(UserInfoModel*)userModel{
[self emptySeeionLocal];


userModel.bg_tableName = QCTUserInfoModelTableName;

userModel.currentHost = currentHost;


BOOL isSave = [userModel bg_save];// 保存方法
if (isSave) {
NSLog(@"token保存成功:%@",userModel.mj_keyValues);


}else{
NSLog(@"token保存失败:%@",userModel.mj_keyValues);


}


}

3.7 注意事项

  • `2020-03-30 19:23:12.877204+0800 Housekeeper[5577:1118700] DB Error: 1 "duplicate column name: BG_CompanyId"

` BGFMDB 不支持大小写,因此保存的对象不能有大小写的两个字段

@property (copy, nonatomic) NSString *companyId;
//@property (strong, nonatomic) NSString *CompanyId;

  • `2020-04-01 16:18:32.127564+0800 retail[8875:1402725] [logging] table QCTUserInfoModelTableName has no column named BG_currentHost

`

调试技巧

如果BGFMDB的表新增字段,可更换一下表名,避免找不到字段,数据更新失败

如果新增字段,就需要更换一下表名

IV see also

公众号:iOS逆向

举报

相关推荐

0 条评论