[技术文档][技术中心][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))×tamp=\(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成功
之前有区分两个登录后做的事情,所以分为两个通知发出。
退出登录时会清空缓存。

你可能感兴趣的:([技术文档][技术中心][iOS部][114啦]帐号登录)