사용자 인증 - Swift SDK
이 페이지의 내용
로그인
익명의 사용자
App Services UI 에서 익명 인증 을 활성화한 경우 사용자는 식별 정보를 제공하지 않고도 앱 에 즉시 로그 할 수 있습니다. 다음 코드는 이를 수행하는 방법을 보여줍니다.
let anonymousCredentials = Credentials.anonymous app.login(credentials: anonymousCredentials) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
이메일/비밀번호 사용자
이메일/비밀번호 인증 을 활성화한 경우 다음 코드를 사용하여 로그인할 수 있습니다.
let email = "skroob@example.com" let password = "12345" app.login(credentials: Credentials.emailPassword(email: email, password: password)) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
API 키 사용자
API 키 인증 을 활성화한 경우 다음 코드를 사용하여 로그인할 수 있습니다.
let credentials = Credentials.userAPIKey("<api-key>") app.login(credentials: credentials) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
사용자 지정 기능 사용자
사용자 지정 함수 인증 제공자 를 활성화한 경우 다음 코드를 사용하여 로그인할 수 있습니다.
let params: Document = ["username": "bob"] app.login(credentials: Credentials.function(payload: params)) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
사용자 지정 JWT 사용자
사용자 지정 JSON 웹 토큰 인증 제공자 를 활성화한 경우 다음 코드를 사용하여 로그인할 수 있습니다.
let credentials = Credentials.jwt(token: "<jwt>") app.login(credentials: credentials) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
Facebook 사용자
Facebook 인증 제공자를 사용하면 기존 Facebook 계정을 사용하여 Facebook 앱을 통해 사용자를 인증할 수 있습니다.
중요
Facebook 프로필 사진 URL 저장 안 함
Facebook 프로필 사진 URL에는 이미지 권한을 부여하는 사용자의 액세스 토큰이 포함되어 있습니다. 보안을 위해 사용자의 액세스 토큰이 포함된 URL을 저장하지 마세요. 대신 이미지를 가져와야 할 때 사용자의 메타데이터 필드에서 직접 URL에 액세스합니다.
iOS 퀵스타트 의 공식 iOS Facebook 을 팔로우하세요. 애플리케이션 에 대한 인증 흐름을 설정하다 합니다. 로그인 완료 핸들러에서 로그인한 사용자의 액세스 토큰 문자열 을 사용하여 App Services Facebook 자격 증명을 생성합니다. 사용자를 App Services 앱 에 로그 합니다.
// This example demonstrates login logic for FBSDK version 13.x. If you're using // a different version of FBSDK, you'll need to adapt this example for your version. let loginManager = LoginManager() loginManager.logIn(permissions: [ .email ]) { loginResult in switch loginResult { case .success(let grantedPermissions, let declinedPermissions, let accessToken): let credentials = Credentials.facebook(accessToken: accessToken!.tokenString) app.login(credentials: credentials) { result in DispatchQueue.main.async { switch result { case .failure(let error): print("Failed to log in to MongoDB Realm: \(error)") case .success(let user): print("Successfully logged in to MongoDB Realm using Facebook OAuth.") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } } } case .failed(let error): print("Facebook login failed: \(error)") case .cancelled: print("The user cancelled the login flow.") } }
Google 사용자
중요
기존 Google 계정으로 사용자를 로그인하려면 애플리케이션에 대해 Google 인증 제공자를 구성하고 활성화해야 합니다.
공식 iOS Google 로그인 통합 가이드를 따르세요. 애플리케이션 에 대한 인증 흐름을 설정하다 합니다. 로그인 완료 핸들러에서 App Services Google 자격 증명을 생성하고 사용자를 App Services App 에 로그 합니다.
자격 증명에 전달하는 값은 제공자에 대한 OpenID Connect 활성화 여부에 따라 달라집니다.
OpenID Connect가 활성화 된 경우
id_token
Google OAuth 응답에 포함된 를 전달합니다. Credentials.googleId(token:).OpenID Connect가 활성화되지 않은 경우 사용자의 서버 인증 코드 를 전달합니다. Credentials.google(serverAuthCode:).
func sign(_ signIn: GIDSignIn!, didSignInFor googleUser: GIDGoogleUser!, withError error: Error!) { if let error = error { print("\(error.localizedDescription)") return } // Get the ID token for the authenticated user so you can pass it to Realm let idToken = googleUser.authentication.idToken! let credentials = Credentials.googleId(token: idToken) app.login(credentials: credentials) { result in DispatchQueue.main.async { switch result { case .failure(let error): print("Failed to log in to MongoDB Realm: \(error)") case .success(let user): print("Successfully logged in to MongoDB Realm using Google OAuth.") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } } } }
func sign(_ signIn: GIDSignIn!, didSignInFor googleUser: GIDGoogleUser!, withError error: Error!) { if let error = error { print("\(error.localizedDescription)") return } // Upon first successful sign-in, forward serverAuthCode credentials to MongoDB Realm. // Upon subsequent sign-ins, this returns nil. let credentials = Credentials.google(serverAuthCode: googleUser.serverAuthCode!) app.login(credentials: credentials) { result in DispatchQueue.main.async { switch result { case .failure(let error): print("Failed to log in to MongoDB Realm: \(error)") case .success(let user): print("Successfully logged in to MongoDB Realm using Google OAuth.") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } } } }
Apple 사용자
Apple 인증으로 로그인 을 활성화한 경우 다음 코드를 사용하여 로그인할 수 있습니다.
// Fetch IDToken via the Apple SDK let credentials = Credentials.apple(idToken: "<token>") app.login(credentials: credentials) { (result) in switch result { case .failure(let error): print("Login failed: \(error.localizedDescription)") case .success(let user): print("Successfully logged in as user \(user)") // Now logged in, do something with user // Remember to dispatch to main if you are doing anything on the UI thread } }
팁
token contains
an invalid number of segments
(이)라는 Login failed
오류가 발생하면 JWT의 UTF-8 인코딩 문자열 버전을 전달하고 있는지 확인하세요.
Async/Await 로그인
버전 10.15.0의 새로운 기능.
App.login 메서드의 비동기/await 버전은 사용자 또는 오류를 비동기적으로 반환합니다.
func login() async { do { let app = App(id: YOUR_APP_SERVICES_APP_ID) // Authenticate with the instance of the app that points // to your backend. Here, we're using anonymous login. let user = try await app.login(credentials: Credentials.anonymous) print("Successfully logged in user: \(user)") } catch { print("Failed to log in user: \(error.localizedDescription)") } }
Realm Swift SDK 버전 10.15.0 및 10.16.0부터 많은 Realm API가 Swift async/await 구문을 지원합니다. 프로젝트는 다음 요구 사항을 충족해야 합니다.
Swift SDK 버전 | Swift 버전 요구 사항 | 지원되는 OS |
---|---|---|
10.25.0 | Swift 5.6 | iOS 13.x |
10.15.0 또는 10.16.0 | Swift 5.5 | iOS 15.x |
앱이 async/await
컨텍스트에서 Realm에 액세스하는 경우 코드를 @MainActor
(으)로 표시하여 스레드 관련 충돌을 방지합니다.
오프라인 로그인
Realm 애플리케이션이 사용자를 인증하면 사용자의 자격 증명을 캐시합니다. 기존 사용자 자격 증명을 확인하여 로그인 흐름을 우회하고 캐시된 사용자에 액세스할 수 있습니다. 이 기능을 사용하여 오프라인에서 영역을 열 수 있습니다.
참고
최초 로그인 시에는 네트워크 연결이 필요합니다.
사용자가 앱에 가입하거나 클라이언트의 기존 계정으로 처음으로 로그인하는 경우 클라이언트가 네트워크에 연결되어 있어야 합니다. 캐시된 사용자 자격 증명을 확인하면 오프라인에서 영역을 열 수 있지만 이는 사용자가 이전에 온라인 상태에서 로그인한 적이 있는 경우에만 가능합니다.
// Log the user into the backend app. // The first time you login, the user must have a network connection. func getUser() async throws -> User { // Check for an existing user. // If the user is offline but credentials are // cached, this returns the existing user. if let user = app.currentUser { return user } else { // If the device has no cached user // credentials, log them in. let app = App(id: YOUR_APP_SERVICES_APP_ID) let loggedInUser = try await app.login(credentials: Credentials.anonymous) return loggedInUser } } let user = try await getUser() var configuration = user.configuration(partitionValue: "Some Partition Value") // Open a Realm with this configuration. // If you do not require the app to download updates // before opening the realm, the realm just opens, even if // offline. let realm = try await Realm(configuration: configuration) print("Successfully opened realm: \(realm)")
사용자 액세스 토큰 받기
Realm SDK는 액세스 토큰을 자동으로 관리하고 만료되면 갱신하며 요청마다 현재 사용자에 대한 유효한 액세스 토큰을 포함합니다.
SDK 외부로 요청을 보내는 경우 각 요청에 사용자의 액세스 토큰을 포함해야 합니다. 이 시나리오에서는 토큰이 만료되면 수동으로 새로 고쳐야 합니다. 액세스 토큰은 30 분 후에 만료됩니다.
로그인한 사용자에 대해 .refreshCustomData() 를 호출하여 사용자의 인증 세션을 새로 고칠 수 있습니다. 그런 다음 코드에서 사용할 수 있는 string 로 .accessToken
를 반환합니다. 다음과 유사한 함수를 사용하여 액세스 토큰을 가져올 수 있습니다.
func getValidAccessToken(user: User) async throws -> String { // An already logged in user's access token might be stale. To // guarantee that the token is valid, refresh it if necessary. try await user.refreshCustomData() return user.accessToken! }
로그인한 사용자가 필요합니다:
let app = App(id: YOUR_APP_SERVICES_APP_ID) let user = try await app.login(credentials: Credentials.anonymous) let accessToken = try await getValidAccessToken(user: user)
토큰 만료 새로 고침
새로 고침 토큰은 일정 시간이 지나면 만료됩니다. 새로 고침 토큰이 만료되면 액세스 토큰을 더 이상 새로 고칠 수 없으며 사용자는 다시 로그인해야 합니다.
영역이 열린 후 새로 고침 토큰이 만료되면 사용자가 다시 로그인할 때까지 장치를 동기화할 수 없습니다. 동기화 오류 처리기는 동기화를 시도할 때 토큰 만료 오류를 포착한 다음 사용자를 로그인 흐름으로 리디렉션하는 로직을 구현해야 합니다.
새로 고침 토큰 만료 구성에 대한 자세한 내용은 App Services 문서에서 사용자 세션 관리를 참조하세요.
로그아웃
로그인한 후 로그아웃할 수 있습니다.
경고
사용자가 로그아웃하면 사용자가 연 동기화된 영역에서 더 이상 데이터를 읽거나 쓸 수 없습니다. 따라서 최초 사용자가 로그아웃하기 전에 아직 완료되지 않은 작업이 성공적으로 완료되지 않으며 오류가 발생할 수 있습니다. 이러한 방식으로 실패한 쓰기 작업의 모든 데이터는 손실됩니다.
app.currentUser?.logOut { (error) in // user is logged out or there was an error }