将来自 Cognito 的用户信息与 AWS Amplify GraphQL 相关联
Associate user information from Cognito with AWS Amplify GraphQL
我在xcode11.4,Swift4。目标是:
在 Cognito 用户池中注册一个新用户,然后使用 Amplify GraphQL 保存关联的用户记录。
使用 Cognito 用户池登录后,CRUD 用户记录。
问题是我不知道如何将 Cognito 与 Amplify GraphQL 相关联。例如,在 Google Firebase auth 和 Firestore 中,我会在注册后获得一个唯一的用户 ID UID
,然后我会在 Firestore
中创建一个关联的用户记录,密钥如下 UID
。然后在用户 signin/authentication 上,我可以从 firebase auth 得到这个 UID
并在 firestore 中找到关联的记录。
目前使用 AWS 堆栈,我在 schema.graphql
中创建了一个用户模型:
type User @model @auth(rules: [{ allow: owner, ownerField: "id", operations: [create, update, delete]}]){
id: ID!
firstName : String
lastName : String
handle : String
email : String!
}
这样只有经过身份验证的用户才能创建、更新和删除。接下来在 SignUpController
的某处我创建了一个新用户:
AWSMobileClient.default().signUp( username: email
, password: password
, userAttributes: ["email": email]) { (signUpResult, error) in
if let signUpResult = signUpResult {
switch(signUpResult.signUpConfirmationState) {
case .confirmed:
self.showAlert(msg: "You already have an account. Please go back and press log in")
case .unconfirmed:
break
case .unknown:
self.showAlert(msg: "Network error")
}
} else if let error = error { ... }
然后用代码确认用户:
AWSMobileClient.default().confirmSignUp(username: email, confirmationCode: code) { (signUpResult, error) in
if let signUpResult = signUpResult {
switch(signUpResult.signUpConfirmationState) {
case .confirmed:
// This is where I need to create an associated user account
break
case .unconfirmed:
self.showAlert(title: "Error", msg: "User is not confirmed and needs verification via \(signUpResult.codeDeliveryDetails!.deliveryMedium) sent at \(signUpResult.codeDeliveryDetails!.destination!)")
case .unknown:
self.showAlert(title: "Error", msg: "Network error")
}
} else { //if let error = error {
self.showAlert(title: "Error", msg: "Network error")
}
目前我在 case .confirmed
中的解决方案是立即登录,然后通过以下方式获取用户的 client token
:
class CognitoPoolProvider : AWSCognitoUserPoolsAuthProviderAsync {
/// this token may not be what you want ...
func getLatestAuthToken(_ callback: @escaping (String?, Error?) -> Void) {
AWSMobileClient.default().getTokens { (token, error) in
if let error = error {
callback(nil,error)
}
callback(token?.accessToken?.tokenString, error)
}
}
}
事实证明这是错误的解决方案,因为用户的客户端令牌一直在变化。
总的来说,这是一个标准的hello-world问题,应该有AWS提供的标准开箱即用的解决方案。我搜索了文档和 github,但找不到满意的答案。
正确的方法是不要信任从 Cognito 创建关联用户信息的客户端,您必须在服务器端执行此操作。
您应该为 Cognito 创建一个新的 Lambda Post 确认触发器并对其进行编码以创建关联帐户。您可以使用 event.userName
或创建自定义属性 uuid 类型,例如 custom:id
到 link 您的关联帐户。
参考:https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-post-confirmation.html
我在xcode11.4,Swift4。目标是:
在 Cognito 用户池中注册一个新用户,然后使用 Amplify GraphQL 保存关联的用户记录。
使用 Cognito 用户池登录后,CRUD 用户记录。
问题是我不知道如何将 Cognito 与 Amplify GraphQL 相关联。例如,在 Google Firebase auth 和 Firestore 中,我会在注册后获得一个唯一的用户 ID UID
,然后我会在 Firestore
中创建一个关联的用户记录,密钥如下 UID
。然后在用户 signin/authentication 上,我可以从 firebase auth 得到这个 UID
并在 firestore 中找到关联的记录。
目前使用 AWS 堆栈,我在 schema.graphql
中创建了一个用户模型:
type User @model @auth(rules: [{ allow: owner, ownerField: "id", operations: [create, update, delete]}]){
id: ID!
firstName : String
lastName : String
handle : String
email : String!
}
这样只有经过身份验证的用户才能创建、更新和删除。接下来在 SignUpController
的某处我创建了一个新用户:
AWSMobileClient.default().signUp( username: email
, password: password
, userAttributes: ["email": email]) { (signUpResult, error) in
if let signUpResult = signUpResult {
switch(signUpResult.signUpConfirmationState) {
case .confirmed:
self.showAlert(msg: "You already have an account. Please go back and press log in")
case .unconfirmed:
break
case .unknown:
self.showAlert(msg: "Network error")
}
} else if let error = error { ... }
然后用代码确认用户:
AWSMobileClient.default().confirmSignUp(username: email, confirmationCode: code) { (signUpResult, error) in
if let signUpResult = signUpResult {
switch(signUpResult.signUpConfirmationState) {
case .confirmed:
// This is where I need to create an associated user account
break
case .unconfirmed:
self.showAlert(title: "Error", msg: "User is not confirmed and needs verification via \(signUpResult.codeDeliveryDetails!.deliveryMedium) sent at \(signUpResult.codeDeliveryDetails!.destination!)")
case .unknown:
self.showAlert(title: "Error", msg: "Network error")
}
} else { //if let error = error {
self.showAlert(title: "Error", msg: "Network error")
}
目前我在 case .confirmed
中的解决方案是立即登录,然后通过以下方式获取用户的 client token
:
class CognitoPoolProvider : AWSCognitoUserPoolsAuthProviderAsync {
/// this token may not be what you want ...
func getLatestAuthToken(_ callback: @escaping (String?, Error?) -> Void) {
AWSMobileClient.default().getTokens { (token, error) in
if let error = error {
callback(nil,error)
}
callback(token?.accessToken?.tokenString, error)
}
}
}
事实证明这是错误的解决方案,因为用户的客户端令牌一直在变化。
总的来说,这是一个标准的hello-world问题,应该有AWS提供的标准开箱即用的解决方案。我搜索了文档和 github,但找不到满意的答案。
正确的方法是不要信任从 Cognito 创建关联用户信息的客户端,您必须在服务器端执行此操作。
您应该为 Cognito 创建一个新的 Lambda Post 确认触发器并对其进行编码以创建关联帐户。您可以使用 event.userName
或创建自定义属性 uuid 类型,例如 custom:id
到 link 您的关联帐户。
参考:https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-post-confirmation.html