Skip to content

Commit 4017fac

Browse files
committed
request_Login_With2FA
1 parent 041a7ed commit 4017fac

5 files changed

Lines changed: 169 additions & 53 deletions

File tree

Coding_iOS/Controllers/Login/LoginViewController.m

Lines changed: 131 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#import "UIImageView+WebCache.h"
1919
#import "EaseInputTipsView.h"
2020

21+
#import "Ease_2FA.h"
22+
2123
@interface LoginViewController ()
2224
@property (nonatomic, strong) Login *myLogin;
2325

@@ -31,6 +33,9 @@ @interface LoginViewController ()
3133
@property (strong, nonatomic) UIImageView *iconUserView, *bgBlurredView;
3234
@property (strong, nonatomic) EaseInputTipsView *inputTipsView;
3335
@property (strong, nonatomic) UIButton *dismissButton;
36+
37+
@property (assign, nonatomic) BOOL is2FAUI;
38+
@property (strong, nonatomic) NSString *otpCode;
3439
@end
3540

3641
@implementation LoginViewController
@@ -169,7 +174,7 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
169174

170175
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
171176
{
172-
return _captchaNeeded? 3 : 2;
177+
return _is2FAUI? 1: _captchaNeeded? 3: 2;
173178
}
174179

175180
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
@@ -181,36 +186,47 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
181186
}
182187
cell.isForLoginVC = YES;
183188
__weak typeof(self) weakSelf = self;
184-
if (indexPath.row == 0) {
189+
190+
if (self.is2FAUI) {
185191
cell.isCaptcha = NO;
186-
[cell configWithPlaceholder:@" 电子邮箱/个性后缀" andValue:self.myLogin.email];
192+
[cell configWithPlaceholder:@" 动态验证码" andValue:self.otpCode];
187193
cell.textField.secureTextEntry = NO;
188194
cell.textValueChangedBlock = ^(NSString *valueStr){
189-
weakSelf.inputTipsView.valueStr = valueStr;
190-
weakSelf.inputTipsView.active = YES;
191-
weakSelf.myLogin.email = valueStr;
192-
[weakSelf.iconUserView setImage:[UIImage imageNamed:@"icon_user_monkey"]];
193-
};
194-
cell.editDidEndBlock = ^(NSString *textStr){
195-
weakSelf.inputTipsView.active = NO;
196-
[weakSelf refreshIconUserImage];
197-
};
198-
}else if (indexPath.row == 1){
199-
cell.isCaptcha = NO;
200-
[cell configWithPlaceholder:@" 密码" andValue:self.myLogin.password];
201-
cell.textField.secureTextEntry = YES;
202-
cell.textValueChangedBlock = ^(NSString *valueStr){
203-
weakSelf.myLogin.password = valueStr;
195+
weakSelf.otpCode = valueStr;
204196
};
205197
cell.editDidEndBlock = nil;
206198
}else{
207-
cell.isCaptcha = YES;
208-
[cell configWithPlaceholder:@" 验证码" andValue:self.myLogin.j_captcha];
209-
cell.textField.secureTextEntry = NO;
210-
cell.textValueChangedBlock = ^(NSString *valueStr){
211-
weakSelf.myLogin.j_captcha = valueStr;
212-
};
213-
cell.editDidEndBlock = nil;
199+
if (indexPath.row == 0) {
200+
cell.isCaptcha = NO;
201+
[cell configWithPlaceholder:@" 电子邮箱/个性后缀" andValue:self.myLogin.email];
202+
cell.textField.secureTextEntry = NO;
203+
cell.textValueChangedBlock = ^(NSString *valueStr){
204+
weakSelf.inputTipsView.valueStr = valueStr;
205+
weakSelf.inputTipsView.active = YES;
206+
weakSelf.myLogin.email = valueStr;
207+
[weakSelf.iconUserView setImage:[UIImage imageNamed:@"icon_user_monkey"]];
208+
};
209+
cell.editDidEndBlock = ^(NSString *textStr){
210+
weakSelf.inputTipsView.active = NO;
211+
[weakSelf refreshIconUserImage];
212+
};
213+
}else if (indexPath.row == 1){
214+
cell.isCaptcha = NO;
215+
[cell configWithPlaceholder:@" 密码" andValue:self.myLogin.password];
216+
cell.textField.secureTextEntry = YES;
217+
cell.textValueChangedBlock = ^(NSString *valueStr){
218+
weakSelf.myLogin.password = valueStr;
219+
};
220+
cell.editDidEndBlock = nil;
221+
}else{
222+
cell.isCaptcha = YES;
223+
[cell configWithPlaceholder:@" 验证码" andValue:self.myLogin.j_captcha];
224+
cell.textField.secureTextEntry = NO;
225+
cell.textValueChangedBlock = ^(NSString *valueStr){
226+
weakSelf.myLogin.j_captcha = valueStr;
227+
};
228+
cell.editDidEndBlock = nil;
229+
}
214230
}
215231
return cell;
216232
}
@@ -261,14 +277,31 @@ - (UIView *)customFooterView{
261277
[footerV addSubview:_loginBtn];
262278

263279

264-
RAC(self, loginBtn.enabled) = [RACSignal combineLatest:@[RACObserve(self, myLogin.email), RACObserve(self, myLogin.password), RACObserve(self, myLogin.j_captcha), RACObserve(self, captchaNeeded)] reduce:^id(NSString *email, NSString *password, NSString *j_captcha, NSNumber *captchaNeeded){
265-
if ((captchaNeeded && captchaNeeded.boolValue) && (!j_captcha || j_captcha.length <= 0)) {
266-
return @(NO);
267-
}else{
268-
return @((email && email.length > 0) && (password && password.length > 0));
269-
}
270-
}];
271-
280+
RAC(self, loginBtn.enabled) = [RACSignal combineLatest:@[
281+
RACObserve(self, myLogin.email),
282+
RACObserve(self, myLogin.password),
283+
RACObserve(self, myLogin.j_captcha),
284+
RACObserve(self, captchaNeeded),
285+
RACObserve(self, is2FAUI),
286+
RACObserve(self, otpCode)
287+
]
288+
reduce:^id(
289+
NSString *email,
290+
NSString *password,
291+
NSString *j_captcha,
292+
NSNumber *captchaNeeded,
293+
NSNumber *is2FAUI,
294+
NSString *otpCode){
295+
if (is2FAUI && is2FAUI.boolValue) {
296+
return @(otpCode.length > 0);
297+
}else{
298+
if ((captchaNeeded && captchaNeeded.boolValue) && (!j_captcha || j_captcha.length <= 0)) {
299+
return @(NO);
300+
}else{
301+
return @((email && email.length > 0) && (password && password.length > 0));
302+
}
303+
}
304+
}];
272305
return footerV;
273306
}
274307

@@ -320,13 +353,13 @@ - (void)configBottomView{
320353

321354
#pragma mark Btn Clicked
322355
- (void)sendLogin{
323-
NSString *tipMsg = [_myLogin goToLoginTipWithCaptcha:_captchaNeeded];
356+
NSString *tipMsg = self.is2FAUI? [self goToLoginTipWith2FA]: [_myLogin goToLoginTipWithCaptcha:_captchaNeeded];
324357
if (tipMsg) {
325358
kTipAlert(@"%@", tipMsg);
326359
return;
327360
}
328-
[self.view endEditing:YES];
329361

362+
[self.view endEditing:YES];
330363
if (!_activityIndicator) {
331364
_activityIndicator = [[UIActivityIndicatorView alloc]
332365
initWithActivityIndicatorStyle:
@@ -339,18 +372,40 @@ - (void)sendLogin{
339372
[_activityIndicator startAnimating];
340373

341374
__weak typeof(self) weakSelf = self;
342-
343375
_loginBtn.enabled = NO;
344-
[[Coding_NetAPIManager sharedManager] request_Login_WithParams:[self.myLogin toParams] andBlock:^(id data, NSError *error) {
345-
weakSelf.loginBtn.enabled = YES;
346-
[weakSelf.activityIndicator stopAnimating];
347-
if (data) {
348-
[Login setPreUserEmail:self.myLogin.email];//记住登录账号
349-
[((AppDelegate *)[UIApplication sharedApplication].delegate) setupTabViewController];
350-
}else{
351-
[weakSelf refreshCaptchaNeeded];
352-
}
353-
}];
376+
377+
if (self.is2FAUI) {
378+
[[Coding_NetAPIManager sharedManager] request_Login_With2FA:self.otpCode andBlock:^(id data, NSError *error) {
379+
weakSelf.loginBtn.enabled = YES;
380+
[weakSelf.activityIndicator stopAnimating];
381+
if (data) {
382+
[Login setPreUserEmail:self.myLogin.email];//记住登录账号
383+
[((AppDelegate *)[UIApplication sharedApplication].delegate) setupTabViewController];
384+
}else{
385+
NSString *status_expired = error.userInfo[@"msg"][@"user_login_status_expired"];
386+
if (status_expired.length > 0) {
387+
[weakSelf changeUITo2FAWithGK:nil];
388+
}
389+
}
390+
}];
391+
}else{
392+
[[Coding_NetAPIManager sharedManager] request_Login_WithParams:[self.myLogin toParams] andBlock:^(id data, NSError *error) {
393+
weakSelf.loginBtn.enabled = YES;
394+
[weakSelf.activityIndicator stopAnimating];
395+
if (data) {
396+
[Login setPreUserEmail:self.myLogin.email];//记住登录账号
397+
[((AppDelegate *)[UIApplication sharedApplication].delegate) setupTabViewController];
398+
}else{
399+
NSString *global_key = error.userInfo[@"msg"][@"two_factor_auth_code_not_empty"];
400+
if (global_key.length > 0) {
401+
[weakSelf changeUITo2FAWithGK:global_key];
402+
}else{
403+
[self showError:error];
404+
[weakSelf refreshCaptchaNeeded];
405+
}
406+
}
407+
}];
408+
}
354409
}
355410

356411
- (IBAction)cannotLoginBtnClicked:(id)sender {
@@ -374,12 +429,37 @@ - (IBAction)goRegisterVC:(id)sender {
374429
}
375430

376431
- (void)dismissButtonClicked{
377-
[self dismissViewControllerAnimated:YES completion:nil];
432+
if (self.is2FAUI) {
433+
self.is2FAUI = NO;
434+
}else{
435+
[self dismissViewControllerAnimated:YES completion:nil];
436+
}
378437
}
379438

380-
- (void)dealloc
381-
{
382-
_myTableView.delegate = nil;
383-
_myTableView.dataSource = nil;
439+
#pragma mark 2FA
440+
- (void)changeUITo2FAWithGK:(NSString *)global_key{
441+
self.otpCode = [OTPListViewController otpCodeWithGK:global_key];
442+
self.is2FAUI = global_key.length > 0;
443+
if (self.otpCode) {
444+
[self sendLogin];
445+
}
446+
}
447+
448+
- (void)setIs2FAUI:(BOOL)is2FAUI{
449+
_is2FAUI = is2FAUI;
450+
if (!_is2FAUI) {
451+
self.otpCode = nil;
452+
}
453+
[self.myTableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:_is2FAUI? UITableViewRowAnimationLeft: UITableViewRowAnimationRight];
454+
}
455+
456+
- (NSString *)goToLoginTipWith2FA{
457+
NSString *tipStr = nil;
458+
if (self.otpCode.length <= 0) {
459+
tipStr = @"动态验证码不能为空";
460+
}else if (![self.otpCode isPureInt] || self.otpCode.length != 6){
461+
tipStr = @"动态验证码必须是一个6位数字";
462+
}
463+
return tipStr;
384464
}
385465
@end

Coding_iOS/Ease_2FA/Controllers/OTPListViewController.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
#import "BaseViewController.h"
1010

1111
@interface OTPListViewController : BaseViewController
12-
12+
+(NSString *)otpCodeWithGK:(NSString *)global_key;
1313
@end

Coding_iOS/Ease_2FA/Controllers/OTPListViewController.m

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,23 @@ @interface OTPListViewController ()<UITableViewDataSource, UITableViewDelegate>
3232

3333
@implementation OTPListViewController
3434

35+
+(NSString *)otpCodeWithGK:(NSString *)global_key{
36+
NSString *otpCode = nil;
37+
if (global_key.length > 0) {
38+
NSArray *otpAccountDictList = [SSKeychain accountsForService:kOTPService];
39+
for (NSDictionary *obj in otpAccountDictList) {
40+
NSString *name = obj[(__bridge id)kSecAttrAccount];
41+
name = [[name componentsSeparatedByString:@"@"] firstObject];
42+
if ([name isEqualToString:global_key]) {
43+
OTPAuthURL *authURL = [OTPAuthURL ease_authURLWithKeychainDictionary:obj];
44+
otpCode = authURL.otpCode;
45+
break;
46+
}
47+
}
48+
}
49+
return otpCode;
50+
}
51+
3552
- (void)viewDidLoad{
3653
[super viewDidLoad];
3754
self.title = @"身份验证器";

Coding_iOS/Util/Manager/Coding_NetAPIManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141

4242
//Login
43+
- (void)request_Login_With2FA:(NSString *)otpCode andBlock:(void (^)(id data, NSError *error))block;
4344
- (void)request_Login_WithParams:(id)params andBlock:(void (^)(id data, NSError *error))block;
4445
- (void)request_Register_WithParams:(id)params andBlock:(void (^)(id data, NSError *error))block;
4546
- (void)request_CaptchaNeededWithPath:(NSString *)path andBlock:(void (^)(id data, NSError *error))block;

Coding_iOS/Util/Manager/Coding_NetAPIManager.m

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,27 @@ - (void)request_UnReadNotificationsWithBlock:(void (^)(id data, NSError *error))
6464
}];
6565
}
6666
#pragma mark Login
67+
- (void)request_Login_With2FA:(NSString *)otpCode andBlock:(void (^)(id data, NSError *error))block{
68+
if (otpCode.length <= 0) {
69+
return;
70+
}
71+
[MobClick event:kUmeng_Event_Request label:@"2FA_Login"];
72+
[[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:@"api/check_two_factor_auth_code" withParams:@{@"code" : otpCode} withMethodType:Post andBlock:^(id data, NSError *error) {
73+
id resultData = [data valueForKeyPath:@"data"];
74+
if (resultData) {
75+
User *curLoginUser = [NSObject objectOfClass:@"User" fromJSON:resultData];
76+
if (curLoginUser) {
77+
[Login doLogin:resultData];
78+
}
79+
block(curLoginUser, nil);
80+
}else{
81+
block(nil, error);
82+
}
83+
}];
84+
}
6785
- (void)request_Login_WithParams:(id)params andBlock:(void (^)(id data, NSError *error))block{
6886
[MobClick event:kUmeng_Event_Request label:@"登录"];
69-
[[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:kNetPath_Code_Login withParams:params withMethodType:Post andBlock:^(id data, NSError *error) {
87+
[[CodingNetAPIClient sharedJsonClient] requestJsonDataWithPath:kNetPath_Code_Login withParams:params withMethodType:Post autoShowError:NO andBlock:^(id data, NSError *error) {
7088
id resultData = [data valueForKeyPath:@"data"];
7189
if (resultData) {
7290
User *curLoginUser = [NSObject objectOfClass:@"User" fromJSON:resultData];

0 commit comments

Comments
 (0)