获取用户信息时增加了simple_token字段,存下来,token过期以后调用 /login/simple_token 重新获得新的认证token

This commit is contained in:
hext 2022-09-14 00:14:19 +08:00
parent 6927a94860
commit ed61f49eca
10 changed files with 166 additions and 3 deletions

View File

@ -49,4 +49,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 42e3d8abd976589c1043ff9f9e864c275a490160
COCOAPODS: 1.11.2
COCOAPODS: 1.11.3

View File

@ -97,6 +97,9 @@
52EB90B32778DA4E0048E0ED /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EB90B22778DA4E0048E0ED /* Line.swift */; };
52EED71E27C9394D0086A804 /* WXDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EED71D27C9394D0086A804 /* WXDelegate.swift */; };
52EED71F27C93B960086A804 /* WXDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EED71D27C9394D0086A804 /* WXDelegate.swift */; };
52EF0AFC28CE081A00C99E4F /* CommonUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EF0AFB28CE081A00C99E4F /* CommonUtils.swift */; };
52EF0AFD28CE081A00C99E4F /* CommonUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EF0AFB28CE081A00C99E4F /* CommonUtils.swift */; };
52EF0AFE28CE08EC00C99E4F /* CommonUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52EF0AFB28CE081A00C99E4F /* CommonUtils.swift */; };
52F0243F277737470071D861 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F0243E277737470071D861 /* LoginView.swift */; };
52F2C223277961D7006F08DC /* SettingsItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F2C222277961D7006F08DC /* SettingsItemView.swift */; };
52F40D2F277CA05600766C24 /* MessageItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52F40D2E277CA05600766C24 /* MessageItemView.swift */; };
@ -218,6 +221,7 @@
52EB90AF2778D67F0048E0ED /* KeyItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyItemView.swift; sourceTree = "<group>"; };
52EB90B22778DA4E0048E0ED /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
52EED71D27C9394D0086A804 /* WXDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WXDelegate.swift; sourceTree = "<group>"; };
52EF0AFB28CE081A00C99E4F /* CommonUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommonUtils.swift; sourceTree = "<group>"; };
52F0243C277733CE0071D861 /* PushDeer.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = PushDeer.entitlements; sourceTree = "<group>"; };
52F0243E277737470071D861 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = "<group>"; };
52F2C222277961D7006F08DC /* SettingsItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsItemView.swift; sourceTree = "<group>"; };
@ -367,6 +371,7 @@
527872C327CE0EE800AD79AD /* Info-SelfHosted.plist */,
52E317DA279305BB000B8BB1 /* Localizable.strings */,
52E317D7279305BB000B8BB1 /* InfoPlist.strings */,
52EF0AFA28CE07A600C99E4F /* Tool */,
52450F362784822C003652D8 /* Service */,
52B8CF5D277DE5FF004CB680 /* Common */,
52450F3D27849228003652D8 /* Model */,
@ -447,6 +452,14 @@
path = Common;
sourceTree = "<group>";
};
52EF0AFA28CE07A600C99E4F /* Tool */ = {
isa = PBXGroup;
children = (
52EF0AFB28CE081A00C99E4F /* CommonUtils.swift */,
);
path = Tool;
sourceTree = "<group>";
};
52F0243D2777370F0071D861 /* View */ = {
isa = PBXGroup;
children = (
@ -776,6 +789,7 @@
5206009E27CF76BC00188431 /* PushDeerApi.swift in Sources */,
520600A627D0AE2300188431 /* Line.swift in Sources */,
5206009D27CF74C100188431 /* HttpRequest.swift in Sources */,
52EF0AFE28CE08EC00C99E4F /* CommonUtils.swift in Sources */,
520600A127CF770600188431 /* Env.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -810,6 +824,7 @@
52EED71E27C9394D0086A804 /* WXDelegate.swift in Sources */,
52EB90AE2778AFD60048E0ED /* BaseNavigationView.swift in Sources */,
524E99E627B3CD0F00292396 /* EndpointView.swift in Sources */,
52EF0AFC28CE081A00C99E4F /* CommonUtils.swift in Sources */,
52EB90AC2778ADF80048E0ED /* CardView.swift in Sources */,
52EB90B02778D67F0048E0ED /* KeyItemView.swift in Sources */,
52AC5C2827B7FE1D00EEB185 /* ViewExtension.swift in Sources */,
@ -853,6 +868,7 @@
52FBA09427874879003308C2 /* ContentView.swift in Sources */,
52B8CF85277E0C12004CB680 /* Line.swift in Sources */,
52AC5C2927B7FE1D00EEB185 /* ViewExtension.swift in Sources */,
52EF0AFD28CE081A00C99E4F /* CommonUtils.swift in Sources */,
52450F402784923D003652D8 /* Result.swift in Sources */,
526A1E712791E00400BA2177 /* PushDeerData.xcdatamodeld in Sources */,
52450F432784943F003652D8 /* HttpRequest.swift in Sources */,

View File

@ -29,6 +29,7 @@ struct UserInfoContent: Codable{
let level: Int
let created_at: String
let updated_at: String
let simple_token: String?
}
struct DeviceItem: Codable, Identifiable{
@ -78,6 +79,12 @@ struct ResultContent: Codable{
let result: Array<String>
}
struct STokenContent: Codable{
let stoken: String?
}
let dateFormatter = DateFormatter()
extension KeyItem {

View File

@ -125,6 +125,35 @@ class AppState: ObservableObject {
}
}
func loginAfter() {
Task {
// UserInfo
self.userInfo = try await HttpRequest.getUserInfo()
var stoken = self.userInfo?.simple_token
if isEmpty(stoken) {
// UserInfo stoken ,
stoken = try await HttpRequest.stokenRegen().stoken
}
if isNotEmpty(stoken) {
// stoken ,
self.saveSTokenToLocal(stoken: stoken)
}
}
}
func saveSTokenToLocal(stoken: String?) -> Void {
let key = "stoken_\(self.api_endpoint)"
getUserDefaults().set(stoken, forKey: key)
}
func getLocalSToken() -> String? {
let key = "stoken_\(self.api_endpoint)"
return getUserDefaults().string(forKey: key)
}
func deleteLocalSToken() -> Void {
let key = "stoken_\(self.api_endpoint)"
getUserDefaults().removeObject(forKey: key)
}
func appleIdLogin(_ result: Result<ASAuthorization, Error>) async throws -> TokenContent {
switch result {
case let .success(authorization):

View File

@ -8,13 +8,63 @@
import Foundation
import Moya
struct TokenAuthorizationPlugin: PluginType {
func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {
if
let url = request.url,
var components = URLComponents(url: url, resolvingAgainstBaseURL: true),
let queryItems = components.queryItems
{
let queryItems_new = queryItems.map { item -> URLQueryItem in
if item.name == "token" {
// token
return URLQueryItem(name: "token", value: AppState.shared.token)
}
return item
}
components.queryItems = queryItems_new
var request_mutable = request
request_mutable.url = components.url
return request_mutable
}
return request
}
}
@MainActor
struct HttpRequest {
static let provider = MoyaProvider<PushDeerApi>(callbackQueue: DispatchQueue.main)
static let provider = MoyaProvider<PushDeerApi>(callbackQueue: DispatchQueue.main, plugins: [TokenAuthorizationPlugin()])
/// , Swift Concurrency (async / await)
static func request<T: Codable>(_ targetType: PushDeerApi, resultType: T.Type) async throws -> T {
do {
return try await _request(targetType, resultType: resultType)
} catch {
if (error as NSError).code == 80403 {
// token
let stoken = AppState.shared.getLocalSToken() // stoken
if isNotEmpty(stoken) {
let token = try? await stokenLogin(stoken: stoken!).token // stoken token
if isNotEmpty(token) {
AppState.shared.token = token! // token
do {
return try await _request(targetType, resultType: resultType) // token
} catch {
throw error //
}
}
AppState.shared.deleteLocalSToken() // stoken , stoken
}
// 退
AppState.shared.token = "" // stoken , token 使
}
throw error // error (stoken, token, )
}
}
static func _request<T: Codable>(_ targetType: PushDeerApi, resultType: T.Type) async throws -> T {
return try await withCheckedThrowingContinuation { continuation in
provider.request(targetType) { result in
switch result {
@ -31,7 +81,6 @@ struct HttpRequest {
if let content = result.content, result.code == 0 {
continuation.resume(returning: content)
} else if result.code == 80403 {
AppState.shared.token = ""
continuation.resume(throwing: NSError(domain: result.error ?? NSLocalizedString("登录过期", comment: "token失效时提示"), code: result.code, userInfo: [NSLocalizedDescriptionKey: result.error ?? NSLocalizedString("登录过期", comment: "token失效时提示")]))
} else {
continuation.resume(throwing: NSError(domain: result.error ?? NSLocalizedString("接口报错", comment: "接口报错时提示"), code: result.code, userInfo: [NSLocalizedDescriptionKey: result.error ?? NSLocalizedString("接口报错", comment: "接口报错时提示")]))
@ -139,4 +188,17 @@ struct HttpRequest {
static func rmAllMessage() async throws -> ActionContent {
return try await request(.rmAllMessage(token: AppState.shared.token), resultType: ActionContent.self)
}
static func stokenLogin(stoken: String) async throws -> TokenContent {
return try await request(.stokenLogin(stoken: stoken), resultType: TokenContent.self)
}
static func stokenRegen() async throws -> STokenContent {
return try await request(.stokenRegen(token: AppState.shared.token), resultType: STokenContent.self)
}
static func stokenRemove() async throws -> STokenContent {
return try await request(.stokenRemove(token: AppState.shared.token), resultType: STokenContent.self)
}
}

View File

@ -42,6 +42,9 @@ enum PushDeerApi {
case rmMessage(token: String, id: Int)
case rmAllMessage(token: String)
case stokenLogin(stoken: String)
case stokenRegen(token: String)
case stokenRemove(token: String)
}
extension PushDeerApi: TargetType {
@ -94,6 +97,13 @@ extension PushDeerApi: TargetType {
return "/message/remove"
case .rmAllMessage:
return "/message/clean"
case .stokenLogin:
return "/login/simple_token"
case .stokenRegen:
return "/simple_token/regen"
case .stokenRemove:
return "/simple_token/remove"
}
}
var method: Moya.Method {
@ -145,6 +155,12 @@ extension PushDeerApi: TargetType {
case let .rmAllMessage(token):
return .requestParameters(parameters: ["token": token],encoding: URLEncoding.queryString)
case let .stokenLogin(stoken):
return .requestParameters(parameters: ["stoken": stoken],encoding: URLEncoding.queryString)
case let .stokenRegen(token):
return .requestParameters(parameters: ["token": token],encoding: URLEncoding.queryString)
case let .stokenRemove(token):
return .requestParameters(parameters: ["token": token],encoding: URLEncoding.queryString)
}
}
var headers: [String: String]? {

View File

@ -30,6 +30,9 @@ class WXDelegate: NSObject, WXApiDelegate {
if state == "login" {
AppState.shared.token = try await HttpRequest.wechatLogin(code: code).token
// AppState token , SwiftUI ContentView
//
AppState.shared.loginAfter()
} else if state == "bind" {
_ = try await HttpRequest.mergeUser(type: "wechat", tokenorcode: code)
// ,

View File

@ -0,0 +1,26 @@
//
// CommonUtils.swift
// PushDeer
//
// Created by HEXT on 2022/9/11.
//
import Foundation
/// ****
/// - Parameter emptiable: , Collection , : String / Array / Dictionary / Set / Data
/// - Returns: nil true
func isEmpty<T: Collection>(_ emptiable: T?) -> Bool {
if emptiable == nil || emptiable!.isEmpty {
return true
} else {
return false
}
}
/// ****
/// - Parameter emptiable: , Collection , : String / Array / Dictionary / Set / Data
/// - Returns: nil false
func isNotEmpty<T: Collection>(_ emptiable: T?) -> Bool {
return !isEmpty(emptiable)
}

View File

@ -41,6 +41,8 @@ struct LoginView: View {
showLoading = true
store.token = try await store.appleIdLogin(result).token
//
//
store.loginAfter()
} catch {
showLoading = false
if (error as NSError).code == 1001 {

View File

@ -21,6 +21,7 @@ struct SettingsView: View {
VStack {
SettingsItemView(title: NSLocalizedString("登录为", comment: "") + " " + userName(), button: NSLocalizedString("退出", comment: "退出登录按钮上的文字")) {
store.token = ""
store.deleteLocalSToken()
HToast.showText(NSLocalizedString("退出", comment: "退出登录按钮上的文字"))
}
.padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20))
@ -37,6 +38,7 @@ struct SettingsView: View {
SettingsItemView(title: NSLocalizedString("API endpoint", comment: ""), button: NSLocalizedString("重置", comment: "")) {
store.api_endpoint = ""
store.token = ""
store.deleteLocalSToken()
}
.padding(EdgeInsets(top: 18, leading: 20, bottom: 0, trailing: 20))
}