PasskeymeSDK 1.0.0

PasskeymeSDK 1.0.0

Justin Crosbie 维护。



  • 作者
  • Justin Crosbie

alt text

Passkeyme iOS SDK

Passkeyme Web SDK 是一个便利的 SDK,用于 Passkeyme 平台 JavaScript/TypeScript 库,它提供简单函数用于处理使用 WebAuthn API 的 passkey 注册和认证。这个库可以帮助您轻松地将基于 passkey 的身份验证集成到您的 Web 应用程序中。

Passkeyme

安装

您可以通过 cocoapods 安装 Passkey SDK

platform :ios, '16.0'

target 'Passkeyme SDK Demo' do
  use_frameworks!

  pod 'PasskeymeSDK', "~> 0.3.0"
end

然后

pod install

用法

导入 SDK

import PasskeymeSDK

创建实例

创建一个 PasskeySDK 实例

let sdk = PasskeymeSDK()

注册 Passkey

要注册 passkey,请使用 passkeyRegister 方法。该方法接受一个挑战字符串作为输入,并返回一个解析到包含凭证的对象的承诺。

sdk.passkeyRegister(challenge: challenge, anchor: self.view.window!) { result in
    switch result {
    case .success(let credential):
        self.completeRegistration(credential: credential)
    case .failure(let error):
        print("Registration error: \(error)")
    }
}

使用 Passkey 进行认证

要使用 passkey 进行认证,请使用 passkeyAuthenticate 方法。该方法接受一个挑战字符串作为输入,并返回一个解析到包含凭证的对象的承诺。

sdk.passkeyAuthenticate(challenge: challenge, anchor: self.view.window!) { result in
    switch result {
    case .success(let credential):
        self.completeAuthentication(credential: credential)
    case .failure(let error):
        print("Authentication error: \(error)")
    }
}

API

passkeyRegister(challenge: string): Promise<{ credential: string }>

•	challenge: A string that represents the challenge provided by your server.
•	Returns: A promise that resolves to an object containing the credential.

passkeyAuthenticate(challenge: string): Promise<{ credential: string }>

•	challenge: A string that represents the challenge provided by your server.
•	Returns: A promise that resolves to an object containing the credential.

示例

这里是一个完整的工作示例。

要运行它,首先前往 Passkeyme 注册,创建一个应用程序,获取 AppID 和 API 密钥,并在 env 中填写

APP_ID=
API_KEY=

您需要在可寻址域后面运行它才能使 Passkeys 正常工作。您可以托管它,或使用 ngrok 来提供服务。您需要遵循 https://passkeyme.com/docs/docs/SDKs/swift-sdk 中的说明

import UIKit
import PasskeymeSDK
import Alamofire

class ViewController: UIViewController {
    
    let sdk = PasskeymeSDK()

    var APP_ID = ""
    var API_KEY = ""
    var backendURL = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        APP_ID = getEnvironmentVar("APP_ID")!
        API_KEY = getEnvironmentVar("API_KEY")!
        backendURL = "https://passkeyme.com/webauthn/\(APP_ID)"
        
        let registerButton = UIButton(type: .system)
        registerButton.setTitle("Register", for: .normal)
        registerButton.addTarget(self, action: #selector(startRegistration), for: .touchUpInside)
        
        let authenticateButton = UIButton(type: .system)
        authenticateButton.setTitle("Authenticate", for: .normal)
        authenticateButton.addTarget(self, action: #selector(startAuthentication), for: .touchUpInside)
        
        let stackView = UIStackView(arrangedSubviews: [registerButton, authenticateButton])
        stackView.axis = .vertical
        stackView.spacing = 20
        stackView.translatesAutoresizingMaskIntoConstraints = false
        
        view.addSubview(stackView)
        NSLayoutConstraint.activate([
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
        ])
    }
    
    @objc func startRegistration() {
        let url = "\(backendURL)/start_registration"
        AF.request(url, method: .post, parameters: nil, encoding: JSONEncoding.default)
            .responseJSON { response in
                switch response.result {
                case .success(let value):
                    if let json = value as? [String: Any], let challenge = json["challenge"] as? String {
                        self.registerPasskey(challenge: challenge)
                    }
                case .failure(let error):
                    print("Error getting registration challenge: \(error)")
                }
            }
    }
    
    func registerPasskey(challenge: String) {
        sdk.passkeyRegister(challenge: challenge, anchor: self.view.window!) { result in
            switch result {
            case .success(let credential):
                self.completeRegistration(credential: credential)
            case .failure(let error):
                print("Registration error: \(error)")
            }
        }
    }
    
    func completeRegistration(credential: String) {
        let url = "\(backendURL)/complete_registration"
        let parameters: [String: Any] = ["credential": credential]
        AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default)
            .responseJSON { response in
                switch response.result {
                case .success(let value):
                    print("Registration completed: \(value)")
                case .failure(let error):
                    print("Error completing registration: \(error)")
                }
            }
    }
    
    @objc func startAuthentication() {
        let url = "\(backendURL)/start_authentication"
        AF.request(url, method: .post, parameters: nil, encoding: JSONEncoding.default)
            .responseJSON { response in
                switch response.result {
                case .success(let value):
                    if let json = value as? [String: Any], let challenge = json["challenge"] as? String {
                        self.authenticatePasskey(challenge: challenge)
                    }
                case .failure(let error):
                    print("Error getting authentication challenge: \(error)")
                }
            }
    }
    
    func authenticatePasskey(challenge: String) {
        sdk.passkeyAuthenticate(challenge: challenge, anchor: self.view.window!) { result in
            switch result {
            case .success(let credential):
                self.completeAuthentication(credential: credential)
            case .failure(let error):
                print("Authentication error: \(error)")
            }
        }
    }
    
    func completeAuthentication(credential: String) {
        let url = "\(backendURL)/complete_authentication"
        let parameters: [String: Any] = ["credential": credential]
        AF.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default)
            .responseJSON { response in
                switch response.result {
                case .success(let value):
                    print("Authentication completed: \(value)")
                case .failure(let error):
                    print("Error completing authentication: \(error)")
                }
            }
    }
    
    
    func getEnvironmentVar(_ name: String) -> String? {
        guard let rawValue = getenv(name) else { return nil }
        return String(utf8String: rawValue)
    }
}