[技术文档][技术中心][iOS部][114啦]帐号登录

需求说明

1、线上保留授权登录,审核时添加帐号密码登录。
2、通过版本号来控制是否显示帐号密码登录。

需求地址

http://192.168.1.75/114la/230/114la_230/#g=1&p=9_0114%E5%95%A6%E5%B8%90%E5%8F%B7%E5%AF%86%E7%A0%81%E7%99%BB%E5%BD%95

核心代码

启动时根据该接口请求是否需要显示帐号密码登录的界面。
该接口需要获取客户端的版本号在URL中。
服务端判断客户端版本号如果大于服务端设定的版本号则返回114la_login_open=1.

static func get114LaBaseURL() -> String {
//        return "http://114larc.com"
        switch YYWApiCenter.getCurrentAPIEvironmentState() {
        case .rc:
            return "http://114larc.com"
        case .gray:
            fallthrough
        case .release:
            return "https://114la.com"
        }
        
    }
//MARK: 检查是否打开114啦登录开关Api
    static func getCheckOpen114laLoginApi() -> String {
        return get114LaBaseURL() + "/q/api" + get114LaCommonVersion() + "/checkVersion"
    }
// MARK: - 检查是否打开114啦帐号登录开关
    static func checkShouldOpen114laLogin() {
        let request = Request()
        request.apiURL = YYWApiCenter.getCheckOpen114laLoginApi()
        request.apiResource = ""
        request.getAsyncWithCompleteHandle { (json, error) -> AnyObject? in
            if let json = json {
                yywDonUseNewAuthLogin = json["114la_login_open"].intValue != 1
                UserDefaults.standard.set(!yywDonUseNewAuthLogin, forKey: "yywDonUseNewAuthLogin")
            }
            return nil
        }
    }

有个全局的方法是根据yywDonUseNewAuthLogin来选择创建哪个登录控制器。

func chooseLoginVC() -> UIViewController {//判断接口开关  跳转不同登录界面.
    if yywDonUseNewAuthLogin {
        //无帐号密码登录的
        return AuthViewController(nibName: String(describing: AuthViewController.self), bundle: nil)
    } else {
        //有帐号密码登录的
        return NewAuthViewController(nibName: String(describing: NewAuthViewController.self), bundle: nil)
    }
    
}

帐号密码登录界面因为键盘弹起后iPhone部分内容横屏会显示不下。
因此该界面限制的屏幕的方向为竖屏。不允许横屏。

//强制iphone竖屏

    var canAutorotate = true

        if UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiom.pad {
            UIDevice.current.setValue(NSNumber(value: UIDeviceOrientation.unknown.rawValue), forKey: "orientation")
            
            UIDevice.current.setValue(NSNumber(value: UIDeviceOrientation.portrait.rawValue), forKey: "orientation")
            
            UIApplication.shared.setStatusBarOrientation(.portrait, animated: false)
        }

override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        canAutorotate = false
    }

override var shouldAutorotate: Bool {
        return canAutorotate
    }
    
    override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
        if UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiom.pad {
            return .portrait
        }
        return .all
    }
    
    override var preferredInterfaceOrientationForPresentation : UIInterfaceOrientation {
        if UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiom.pad {
            return .portrait
        }
        return .portraitUpsideDown
    }
  • 帐号密码登录:
    LaDateTool.shared.laDateString :网络拉取的时间 --- 系统的时间可能被修改
    authkey 计算公式: sha1( "(username)_sha1(password)IOS(MMddyy)")
//114啦帐号密码登录
   class func loginWith114Account(_ account: String, _ password: String) {
      if reachability?.isReachable() == false {
         MBProgressHUD.showFailImage("网络异常,请检查网络连接")
         return
      }
      MBProgressHUD.showGIFView(HUDWaitingAnimationView.shared.startAnimation(), text: "正在登录")
      
      let sha1Pwd = password.sha1Hash ?? ""
      var params = [String:Any]()
      params["username"] = account
      params["pwd"] = sha1Pwd
      params["appkey"] = "f7a30e1a01944368e0e4"
      params["type"] = "browser"
      params["authkey"] = "\(account)_\(sha1Pwd)_IOS_\(LaDateTool.shared.laDateString)".sha1Hash ?? ""
      params["app"] = 1
      
      let paramString = params.buildStringFromDictionary().addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) ?? params.buildStringFromDictionary()
      guard let url = URL(string: YYWApiCenter.get114AccountLoginApi() + "?" + paramString) else { return }
      let requset = URLRequest(url: url, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 30.0)
      
      let urlSession = URLSession(configuration: URLSessionConfiguration.default)
      
      let task = urlSession.dataTask(with: requset) { (data, respone, error) in
         DispatchQueue.main.async {
            if let data = data {
               let json = JSON.init(data: data)
               HUDWaitingAnimationView.shared.stopAnimation()
               if json["status"].intValue == 1 {
                  //成功登录就记录下用户帐号及头像
                  let user = User(laDict: json["data"].rawDictionary)
                  UserCenter.shared().user = user
                  
                  let loginDic:[String:String] = ["user_account": account, "user_logo": json["data"]["face"].rawString, "user_id": user.laUserID, "user_pwd": password.sha1Hash ?? ""]
                  
                  UserDefaults.standard.set(json["data"].rawDictionary, forKey: "defaults_114laUser_authdata")
                  
                  UserDefaults.standard.set(loginDic, forKey: "last_114laUser_info")
                  
                  
                  MBProgressHUD.show(kMBProgressHUDImageSuccess, text: "登录成功")
                  
                  NotificationCenter.default.post(name: Notification.Name(rawValue: "login114Completed"), object: nil)
                  
                  guard let navigationController = UIApplication.shared.delegate?.window??.rootViewController as? UINavigationController else { return }
                  for (index,vc) in navigationController.viewControllers.enumerated() {
                     if vc is NewAuthViewController {
                        let popVc = navigationController.viewControllers[index-1]
                        navigationController.popToViewController(popVc, animated: true)
                        return
                     }
                  }
               
                  if let nav = navigationController.presentedViewController as? UINavigationController {//可能在说明书多级分类界面中进入,要这样退出该界面。
                     for (index,vc) in nav.viewControllers.enumerated() {
                        if vc is NewAuthViewController {
                           let popVc = nav.viewControllers[index-1]
                           nav.popToViewController(popVc, animated: true)
                           return
                        }
                     }
                  }
                  
//                  loginService.bind115MsgLogin(json["data"]["token"].rawString)
                  
               } else {
                  var error_msg = "帐号或密码错误"
                  if json["info"].stringValue != "参数错误" {
                     error_msg = json["info"].stringValue
                  }
                  MBProgressHUD.showFailImage(error_msg)
               }
            } else {
               HUDWaitingAnimationView.shared.stopAnimation()
               MBProgressHUD.showFailImage("网络异常,请检查网络连接")
            }
         }
      }
      task.resume()
   }
  • 授权登录:
    授权登录是根据以下方法生成nonce传给115或115+。
func gotoAuthToOOF(_ strApp: String) {
      let timeStamp = String(format: "%.f", Date().timeIntervalSince1970)
      let arcMd5 = String(format: "%.f", arc4random()).md5()
      strNonce = "114laver=\(YYWApiCenter.getBrowserVersion())&nonce=\(String(describing: arcMd5))&timestamp=\(timeStamp)"
      
        guard let tempStrNonce = CryptHelper.browserAES256Encrypt(strNonce, key: CryptHelper.generateBrowserKey()) else {
            print("gotoAuthToOOF:-tempStrNonce=nil")
            return
        }
        let strOOF = "\(strApp)://login.com/auth?nonce=\(String(describing: tempStrNonce))"
        AppDelegate.openOOFURL(URL(string: strOOF)!, {_ in 
            
        })
    }

然后115再请求114啦服务器,有帐号直接返回相互绑定好的帐号114la_token与115帐号的信息

if let strRes = results["res"], url.absoluteString.hasPrefix("oof.browser://login.com/auth") {
                if let _ = UserDefaults.standard.object(forKey: "defaults_user_authdata") {
                    MBProgressHUD.show(kMBProgressHUDImageWarning, text: "已有帐号登录")
                    return true
                }
                let strd = strRes.ud_UrlDecoded() as String
                let resData = CryptHelper.browserAES256Decrypt(with: CryptHelper.data(withBase64EncodedString: strd), key: CryptHelper.generateAuthClientKey()) ?? Data()
                if let strDecode = String(data: resData, encoding: String.Encoding.utf8) {
                    let result = JSON.parse(string: strDecode)
                    if result != JSON.null {
                        if result["state"].boolValue == true {
                            if let data = result["data"].object as? [String : Any] {
                                if let token = data["114la_token"] as? String {
                                    loginService.authLogin114la(token, offData: data)
                                    return true
                                }
                            }
                        }else{
                            if let errmsg = result["message"].object as? String {
                                MBProgressHUD.show(kMBProgressHUDImageFail, text: "登录失败\r\n\(errmsg)")
                            }
                            return false
                        }
                    }
                }
                MBProgressHUD.show(kMBProgressHUDImageFail, text: "已取消\r\n解密失败")
                return false
            }

最后根据115返回的114la_token去获取114啦帐号相关信息。

/*
    static let regMobileAppKey = "f7a30e1a01944368e0e4"
    
 115第三方登录
     POST 请求
     openid true    string  115登录返回的唯一串
     app    true    int 客户端类型,ios传1;安卓端传2
     appkey true    string  固定值;各个频道不一致。
     authkey    true    string  app=1时:sha1(openid_IOS_MMDDYY);app=2时:
     sha1(openid_ANDROID_MMDDYY);
     */
    static func authLogin114la(openid: String, _ handle: @escaping CompletionHandle) -> Void {
        let request = YYW114LaRequest()
        request.params["openid"] = openid
        request.params["app"] = 1
        request.params["appkey"] = regMobileAppKey
        request.params["authkey"] = "\(openid)_IOS_\(LaDateTool.shared.laDateString)".sha1Hash ?? ""
        request.apiURL = "http://my.114la.com/app/open115login"
        request.apiResource = ""
        request.postAsyncWithCompleteHandle(handle)
    }

登录成功后则创建user对象,并缓存用户信息,并发出登录成功的通知。
当需要在登录成功时做事情时可以直接添加通知观察者。
通知名:
"login114Completed" 登录114啦成功
"loginCompleted" 登录115成功
之前有区分两个登录后做的事情,所以分为两个通知发出。
退出登录时会清空缓存。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容