123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- //
- // RQUserManager.m
- // BuckDriverStudent
- //
- // Created by 张嵘 on 2019/10/24.
- // Copyright © 2019 RONG. All rights reserved.
- //
- #import "RQUserManager.h"
- //#import "RQHTTPService+RQUpdateUser.h"
- #import "RQLoginViewModel.h"
- #include <CommonCrypto/CommonCrypto.h>
- /// 用户信息的名称
- static NSString * const RQUserDataFileName = @"senba_empty_user.data";
- /// 用户数据配置完成
- NSString *const RQUserDataConfigureCompleteNotification = @"RQUserDataConfigureCompleteNotification";
- /// 用户数据配置完成,取出userInfo 数据的的key
- NSString *const RQUserDataConfigureCompleteUserInfoKey = @"RQUserDataConfigureCompleteUserInfoKey";
- @interface RQUserManager ()
- /// currentLoginUser
- @property (nonatomic, readwrite, strong) RQUserModel *currentUser;
- @property (nonatomic, readwrite, assign) BOOL isObserve;
- @property (nonatomic, readwrite, strong) RQLoginViewModel *loginViewModel;
- @end
- @implementation RQUserManager
- static id rq_userManager = nil;
- #pragma mark - init
- + (instancetype)sharedInstance {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- rq_userManager = [[self alloc] init];
- });
- return rq_userManager;
- }
- - (instancetype)init {
- if (self = [super init]) {
-
- }
- return self;
- }
- #pragma mark - Private Method
- - (void)saveUser:(RQUserModel *)user {
- /// 记录用户数据
- self.currentUser = user;
- /// 保存
- BOOL status = [NSKeyedArchiver archiveRootObject:user toFile:RQFilePathFromWeChatDoc(RQUserDataFileName)];
- NSLog(@"Save login user data, the status is %@",status?@"Success...":@"Failure...");
- if (_currentUser && !_isObserve) {
- [self beginObserveUser];
- }
- }
- - (void)deleteUser:(RQUserModel *)user{
- /// 删除
- self.currentUser = nil;
- BOOL status = [RQFileManager removeFile:RQFilePathFromWeChatDoc(RQUserDataFileName)];
- NSLog(@"Delete login user data , the status is %@",status?@"Success...":@"Failure...");
- self.currentUser = nil;
- _isObserve = !status;
- self.isVip = 0;
- }
- - (RQUserModel *)currentUser {
- if (!_currentUser) {
- _currentUser = [NSKeyedUnarchiver unarchiveObjectWithFile:RQFilePathFromWeChatDoc(RQUserDataFileName) exception:nil];
- if (_currentUser && !_isObserve) {
- [self beginObserveUser];
- }
- }
- return _currentUser;
- }
- /// 是否登录
- - (BOOL)isLogin {
- if (RQObjectIsNil(self.currentUser)) {
- return NO;
- } else {
- return YES;
- }
- }
- /// 是否需要登录
- - (BOOL)isShouldLogin {
- if (RQObjectIsNil(self.currentUser)) {
- if (![RQControllerHelper.currentViewController isKindOfClass:[RQLoginViewController class]]) {
- [RQ_APPDELEGATE.services pushViewModel:self.loginViewModel animated:YES];
- }
- return NO;
- } else {
- return YES;
- }
- }
- /// 获取当前用户的id
- - (NSString *)currentUserId {
- if ([self currentUser].thirdResult) {
- return RQStringIsNotEmpty(self.currentUser.userId)? self.currentUser.userId : @"";
- } else if ([self currentUser].appleUserInfo) {
- return [self currentUser].appleUserInfo.sub;
- } else {
- return @"";
- }
- }
- - (void)loginUser:(RQUserModel *)user{
- /// 保存用户
- [self saveUser:user];
-
- /// 发送登录成功的通知
- [self postUserDataConfigureCompleteNotification];
-
- [RQ_USER_MANAGER isVipWithComplete:^(NSInteger isVip) {}];
- /// 同步本地错题·收藏
- // [RQ_UPDATE_LOCALDATA_MANAGER updateLocalWrongAndCollectionWithComplete:nil];
- /// 设置别名
- // [SBJPushService setAlias];
- }
- /// 退出登录
- - (void)logoutUser{
- RQUserModel *currentUser = [self currentUser];
- currentUser.channel = RQUserLoginChannelTypeDefault;
- [self saveUser:currentUser];
- /// 删除别名
- // [SBJPushService deleteAlias];
- //
- // /// 删除token
- // [self deleteToken];
-
- /// 删除用户数据
- [self deleteUser:currentUser];
- [RQ_SDJK_DB_MANAGER deleteAllWrongModelsWithComplete:nil];
- [RQ_SDJK_DB_MANAGER deleteAllCollectionModelsWithComplete:nil];
- [RQ_CACHE_MANAGER removeCacheWithPath:RQ_GET_VipInfo parameters:nil];
- }
- /// 用户信息配置完成
- - (void)postUserDataConfigureCompleteNotification{
- RQUserModel *user = [self currentUser];
- [RQNotificationCenter postNotificationName:RQUserDataConfigureCompleteNotification object:nil userInfo:@{RQUserDataConfigureCompleteUserInfoKey:user}];
- }
- - (void)beginObserveUser {
- _isObserve = YES;
- // [[RACSignal combineLatest:@[[RACObserve(self.currentUser, nickName) distinctUntilChanged], [RACObserve(self.currentUser, userName) distinctUntilChanged], [RACObserve(self.currentUser, sex) distinctUntilChanged], [RACObserve(self.currentUser, birthday) distinctUntilChanged], [RACObserve(self.currentUser, carType) distinctUntilChanged], [RACObserve(self.currentUser, email) distinctUntilChanged], [RACObserve(self.currentUser, address) distinctUntilChanged], [RACObserve(self.currentUser, password) distinctUntilChanged]] reduce:^(NSString *nickName, NSString *userName, NSString *sex, NSString *birthday, NSString *carType, NSString *email, NSString *address, NSString *password) {
- // return self.currentUser;
- // }] subscribeNext:^(RQUserModel *userModel) {
- // [self updateUserData];
- // }];
- }
- /// 比对本地网络数据
- - (void)updateUserData {
- // [[RQ_HTTP_Service updateUserWithID:self.currentUser.id userName:self.currentUser.userName sex:self.currentUser.sex birthday:self.currentUser.birthday email:self.currentUser.email address:self.currentUser.address nickName:self.currentUser.nickName password:self.currentUser.password photoContent:self.currentUser.photoContent carType:self.currentUser.carType idCard:self.currentUser.idCard] subscribeNext:^(RQUserModel *userModel) {
- // userModel.channel = RQ_USER_MANAGER.currentUser.channel;
- // [self willChangeValueForKey:@"user"];
- // /// user模型的数据 重置,但是user的 指针地址不变
- // [self.currentUser mergeValuesForKeysFromModel:userModel];
- // [self didChangeValueForKey:@"user"];
- // } error:^(NSError * _Nullable error) {
- // [MBProgressHUD rq_showErrorTips:error];
- // }];
- }
- - (NSString *)headImage {
- if ([self currentUser].thirdResult) {
- return RQStringIsNotEmpty(self.currentUser.thirdResult.headimgurl)? self.currentUser.thirdResult.headimgurl : (RQObjectIsNil(self.currentUser.thirdResult.data)? @"" : (RQStringIsNotEmpty(self.currentUser.thirdResult.data.avatar)? self.currentUser.thirdResult.data.avatar : @""));
- } else if ([self currentUser].appleUserInfo) {
- return @"";
- } else {
- return @"";
- }
- }
- - (NSString *)nickName {
- if (self.currentUser) {
- return self.currentUser.nickName;
- } else {
- return @"游客";
- }
- }
- /// 是否Vip
- - (void)isVipWithComplete:(VoidBlock_integer)complete {
- __block BOOL isVerify;
- if (RQ_USER_MANAGER.isShouldLogin) {
- [RQ_COMMON_MANAGER checkVersionWithComplete:^(BOOL isOpen) {
- [[RQ_HTTP_Service getVipInfo] subscribeNext:^(RQGetVipInfoModel *getVipInfoModel) {
- RQUserModel *userModel = self.currentUser;
- userModel.userId = getVipInfoModel.userId;
- userModel.nickName = getVipInfoModel.nickName;
- userModel.headImage = getVipInfoModel.headImage;
- [self saveUser:userModel];
- //rsa 公钥
- NSString *publicKey = [NSString stringWithFormat:@"%@%@%@",@"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCzR04LMmDlwyVRfK+Kgsm/vFMOFyqvGk4QIVC",@"Gj2CKKfhycRExm15N3tKOOouIjl/EU79It45oS+ltJkscvYrJn1zz+1bSoBLelZzJrn7K0NpHF8k", @"bCprsFHd60x+YJ4l8C3SDxfFebo4kqveJzx6JNZKwzFm7LPEO5XB9pEBRwIDAQAB"];
- BOOL isApple = RQStringIsEmpty(getVipInfoModel.unionId);
- // 构造被签名串
- NSString *verifyString = [NSString stringWithFormat:@"%@%ld",isApple? @"" : getVipInfoModel.unionId,getVipInfoModel.isVip];
-
- //公钥验签
- isVerify = [self verify:verifyString signature:getVipInfoModel.sign withPublivKey:publicKey];
- NSLog(@"验签通过了吧------%@", isVerify ? @"YES":@"NO");
- if (!isVerify) {
- [RQ_CACHE_MANAGER removeCacheWithPath:RQ_GET_VipInfo parameters:nil];
- }
- if (complete) {
- if (isOpen) {
- complete(2);
- } else {
- if (isApple) {
- RQ_USER_MANAGER.isVip = 3;
- complete(3);
- } else {
- RQ_USER_MANAGER.isVip = getVipInfoModel.isVip;
- complete(isVerify? RQ_USER_MANAGER.isVip : 0);
- }
- }
- }
- } error:^(NSError * _Nullable error) {
- if (isOpen) {
- complete(2);
- } else {
- [MBProgressHUD rq_showErrorTips:error];
- if (complete) {
- RQ_USER_MANAGER.isVip = 0;
- complete(0);
- }
- }
- }];
- }];
- } else {
- complete(0);
- }
- }
- /// 是否Vip
- - (void)isShouldVipWithComplete:(VoidBlock_integer)complete {
- [self isVipWithComplete:^(NSInteger isVip) {
- if (complete) {
- /// RQ_MARK:不是会员 暂时判定是会员
- if (isVip <= 0) {
- if (RQ_USER_MANAGER.isLogin) {
- [RQ_Profile_Module showVIPAlertWithComplete:^(BOOL isSuccess) {
- complete(isSuccess);
- }];
- } else {
- complete(isVip);
- }
- } else {
- complete(isVip);
- }
- }
- }];
- }
- // verify Signature
- - (BOOL)verify:(NSString *)content signature:(NSString *)signature withPublivKey:(NSString *)publicKey {
-
- SecKeyRef publicKeyRef = [self addPublicKey:publicKey];
- if (!publicKeyRef) { NSLog(@"添加公钥失败"); return NO; }
- NSData *originData = [self sha256:content];
- NSData *signatureData = [[NSData alloc] initWithBase64EncodedString:signature options:NSDataBase64DecodingIgnoreUnknownCharacters];
- if (!originData || !signatureData) { return NO; }
- OSStatus status = SecKeyRawVerify(publicKeyRef, kSecPaddingPKCS1SHA256, [originData bytes], originData.length, [signatureData bytes], signatureData.length);
-
- if (status ==noErr) { return YES; }
- else{ NSLog(@"验签失败:%d",status); return NO; }
- }
- // digest message with sha1
- - (NSData *)sha256:(NSString *)str
- {
- const void *data = [str cStringUsingEncoding:NSUTF8StringEncoding];
- CC_LONG len = (CC_LONG)strlen(data);
- uint8_t * md = malloc( CC_SHA256_DIGEST_LENGTH * sizeof(uint8_t) );;
- CC_SHA256(data, len, md);
- return [NSData dataWithBytes:md length:CC_SHA256_DIGEST_LENGTH];
- }
- - (SecKeyRef)addPublicKey:(NSString *)pubKey {
- NSData *data = [[NSData alloc] initWithBase64EncodedString:pubKey options:NSDataBase64DecodingIgnoreUnknownCharacters];
-
- //a tag to read/write keychain storage
- NSString *tag = @"RSA_PUBLIC_KEY";
- NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];
-
- // Delete any old lingering key with the same tag
- NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init];
- [publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];
- [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
- [publicKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];
- SecItemDelete((__bridge CFDictionaryRef)publicKey);
-
- // Add persistent version of the key to system keychain
- [publicKey setObject:data forKey:(__bridge id)kSecValueData];
- [publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)kSecAttrKeyClass];
- [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef];
-
- CFTypeRef persistKey = nil;
- OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);
- if (persistKey != nil){
- CFRelease(persistKey);
- }
-
- if ((status != noErr) && (status != errSecDuplicateItem)) { return nil; }
-
- [publicKey removeObjectForKey:(__bridge id)kSecValueData];
- [publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
- [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
- [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
-
- // Now fetch the SecKeyRef version of the key
- SecKeyRef keyRef = nil;
- status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);
- if(status != noErr){
- return nil;
- }
- return keyRef;
- }
- - (void)setTryLookCount:(NSInteger)tryLookCount {
- NSString *key = [NSString stringWithFormat:@"RQTryLookCountKey-%@",RQ_USER_MANAGER.currentUserId];
- [RQ_COMMON_MANAGER saveObjectWithObject:[NSNumber numberWithInteger:tryLookCount] ForKey:key];
- }
- - (NSInteger)tryLookCount {
- NSString *key = [NSString stringWithFormat:@"RQTryLookCountKey-%@",RQ_USER_MANAGER.currentUserId];
- id object = [RQ_COMMON_MANAGER getObjectWithKey:key];
- if (RQObjectIsNil(object)) {
- return 5;
- } else {
- NSInteger tryLookCount = [object integerValue];
- return tryLookCount;
- }
- }
- #pragma mark - LazyLoad
- - (RQLoginViewModel *)loginViewModel {
- if (!_loginViewModel) {
- _loginViewModel = [[RQLoginViewModel alloc] initWithServices:RQ_APPDELEGATE.services params:nil];
- }
- return _loginViewModel;
- }
- @end
|