Discuz iOS应用开发 - bigApp iOS源码分析 - 用户登录流程

用户登录流程

点击登录按钮,最终调用的Http请求为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
- (void)request_Login_WithUserName:(NSString *)username andPassWord:(NSString *)password andFid:(NSString *)fid andQuestionid:(NSString *)questionid andAnswer:(NSString *)answer andBlock:(void (^)(UserModel *data, NSError *error,NSString *message))block
{
NSDictionary *dic = @{@"version":@"1",@"module":@"login",@"loginsubmit":@"yes",@"infloat":@"yes",@"lssubmit":@"yes",@"inajax":@"1",@"fastloginfield":@"username",@"username":username,@"password":password,@"cookietime":@"259200000",@"quickforward":@"yes",@"handlekey":@"ls",@"questionid":avoidNullStr(questionid),@"answer":avoidNullStr(answer)};

[[ClanNetAPI sharedJsonClient] requestJsonDataWithPath:_kurl_base_path withParams:dic withMethodType:Get andBlock:^(id data, NSError *error)
{
if (error) {
block(nil,error,nil);
}else{
id resultData = [data valueForKeyPath:@"Variables"];
DLog(@"%@",data);
if ([resultData objectForKey:@"auth"] && ![[resultData objectForKey:@"auth"] isEqual:[NSNull null]]) {
[ClanNetAPI saveCookieData];
[[NSUserDefaults standardUserDefaults] setObject:username forKey:@"kLASTUSERNAME"];
UserModel *user = [UserModel currentUserInfo];
[user setValueWithObject:[UserModel objectWithKeyValues:data[@"data"]]];
//设置登录成功
user.logined = YES;
[UserModel saveToLocal];
if (fid) {
[self request_checkPostWithFid:fid];
}
block(user, nil,nil);
}else{
NSDictionary *errMes = data[@"Message"];
NSString *messStr = @"密码错误,请重试";
if (errMes) {
messStr = errMes[@"messagestr"];
}
//密码错误
block(nil,nil,messStr);
}
}
}];
}

  • basePath: api/mobile/iyz_index.php
  • Params:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    NSDictionary *dic = @{
    @"version":@"1",
    @"module":@"login",
    @"loginsubmit":@"yes",
    @"infloat":@"yes",
    @"lssubmit":@"yes",
    @"inajax":@"1",
    @"fastloginfield":@"username",
    @"username":username,
    @"password":password,
    @"cookietime":@"259200000",
    @"quickforward":@"yes",
    @"handlekey":@"ls",@"questionid":avoidNullStr(questionid),
    @"answer":avoidNullStr(answer)
    };

在plugin/bigapp/api/1中可以找到定义的login.php模块,最终调用的登录函数为:

1
$result = userlogin($userName, $password, $questionid, $answer, 'username', $_G['clientip']);

我们可以在source/function/function_member.php中找到对应的函数原型。(有可能不对?)
暂时不清楚这两个文件是如何关联的。

  • returnValue:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     {
    Message = {
    messagestr = "\U767b\U5f55\U6210\U529f";
    messageval = "login_succeed";
    };
    Variables = {
    auth = "in order to be comapatible";
    };
    data = {
    accessmasks = 0;
    adminid = 0;
    allowadmincp = 0;
    avatarstatus = 0;
    conisbind = 0;
    email = "test@hotmail.com";
    emailstatus = 0;
    extgroupids = "";
    freeze = 0;
    groupexpiry = 0;
    groupid = 10;
    newpm = 0;
    newprompt = 0;
    notifysound = 0;
    onlyacceptfriendpm = 0;
    regdate = 1495353072;
    status = 0;
    timeoffset = 9999;
    uid = 2;
    username = Test;
    videophotostatus = 0;
    };
    "error_code" = 0;
    "error_msg" = "\U767b\U5f55\U6210\U529f";
    }

data是返回的用户信息,来自主用户表

用户如果保存在iOS应用本地

1
2
3
4
5
6
7
8
9
10
11
12
13
if ([resultData objectForKey:@"auth"] && ![[resultData objectForKey:@"auth"] isEqual:[NSNull null]]) {
[ClanNetAPI saveCookieData];
[[NSUserDefaults standardUserDefaults] setObject:username forKey:@"kLASTUSERNAME"];
UserModel *user = [UserModel currentUserInfo];
[user setValueWithObject:[UserModel objectWithKeyValues:data[@"data"]]];
//设置登录成功
user.logined = YES;
[UserModel saveToLocal];
if (fid) {
[self request_checkPostWithFid:fid];
}
block(user, nil,nil);
}

可以看到的是,如果用户登录成功,所做的步骤:

  • 保存cookies到NSUserDefaults的Code_CookieData键值

    1
    2
    3
    4
    NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject: cookiesData forKey: Code_CookieData];
    [defaults synchronize];
  • 保存用户名到NSUserDefaults的@”kLASTUSERNAME”键值

  • 将data的内容更新到单例UserModel中,并设置登录状态为YES,最后保存单例的内容。(保存到NSUserDefaults的kKEY_CURRENT_USER键值)
  • 验证发帖权限 (Todo,low priority?)

再次打开APP时,用户会直接登录:
直接读取了单例UserModel的内容以及NSUserDefaults的Code_CookieData键值中保存的Cookies

用户退出登录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- (void)logout
{
[ShareSDK cancelAuthorize:SSDKPlatformTypeSinaWeibo];
[ShareSDK cancelAuthorize:SSDKPlatformTypeWechat];
[ClanNetAPI removeCookieData];
UserModel *user = [UserModel new];
NSArray *properties = [UserModel propertiesForClass:[user class]];
for (NSString *property in properties) {
id value = [user valueForKey:property];
SEL sel = NSSelectorFromString(property);
if ([self respondsToSelector:sel]) {
[self setValue:value forKey:property];
}
}
[UserModel saveToLocal];
[UserModel currentUserInfo].logined = NO;
[UserModel saveToLocal];
//清除信息
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:0] forKey:@"KNEWS_MESSAGE"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"KNEWS_MESSAGE_COME" object:nil];
[[NSUserDefaults standardUserDefaults] setObject:@"0" forKey:@"KNEWS_FRIEND_MESSAGE"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"KNEWS_FRIEND_MESSAGE" object:nil];
[[NSUserDefaults standardUserDefaults] setObject:nil forKey:ClanFormhash];
}

  • 移除QQ,微信的认证
  • 删除NSUserDefaults的Code_CookieData键值中保存的Cookies
  • 重置UserModel,并设置为退出登录状态
  • 移除其他信息 (Todo)

工时:

  1. 0.5 day