AWS Cognito包含User Pool和Identity Pool兩個產(chǎn)品纸颜〔蒙基于User Pool可以快速實現(xiàn)一套用戶系統(tǒng)蹦肴。Identity Pool用于實現(xiàn)聯(lián)合身份認證髓窜。User Pool跟Identity Pool的關系如下面幾張圖所示相满。
通過AWS labs的demo可以體驗Cognito的主要功能,github地址:https://github.com/awslabs/aws-sdk-ios-samples录择。
User Pool
aws-sdk-ios-samples里面CognitoYourUserPools-Sample
和CognitoAuth-Sample
兩個demo跟User Pool里面有關拔莱。要把這兩個demo跑起來碗降,要先在User Pool里面添加一個pool,接著添加一個App塘秦,再接著修改項目里面對應的配置讼渊。
CognitoYourUserPools-Sample
支持注冊、登錄尊剔、找回密碼等功能爪幻。
還有更簡單的使用方式,那就是User Pool會提供一個OIDC server挨稿。
https://wla.auth.ap-southeast-2.amazoncognito.com/login?
response_type=code
&client_id=1t80si9ch1voi0bdusm5c9svn
&state=00a4715e-13b3-4da3-8553-dcc757d1d544
&redirect_uri=wla://signin
&scope=openid
&code_challenge=CHdOC4yZEQWOg3jZNCTm8b8v8jPnKjizRipIF0ltvr8
&code_challenge_method=S256
在控制臺可以配置icon奶甘、前景色和背景色。之后點擊Sign in
按鈕钉赁,會在In-App browser里面打開下面這個頁面,挺好看的。
看起來這是一個標準的OIDC服務器逮京,可以看看它的Discovery懒棉,然后就會發(fā)現(xiàn)其實也不是那么標準策严,里面有authorization_endpoint妻导,并沒有看到token_endpoint∑岸裕看demo里面的玩法就更野了硕蛹,根本不來請求這個Discovery馁蒂,而是要使用Info.plist里面的AWS
的配置去拼這些endpoint普监。
上面兩個demo中都可以注冊賬號毙玻,可以在控制臺里面看到這些賬號桑滩。
為了滿足用戶多樣的需求运准,User Pool在很多環(huán)節(jié)都可以設置Lambda function缭受,非常有用。
Identity Pool
CognitoSync-Sample
這個demo是展示Identity Pool功能的米者,這個demo就有點太粗糙了,居然也沒有加入User Pool登錄蔓搞。
我配置了一下Facebook登錄胰丁,登錄了一下試試喂分,感覺還挺溜妻顶。
token
User Pool登錄成功得到的信息如下所示酿愧。看起來是OAuth那一套汇恤,這個AccessToken很長庞钢,是一個JWT Bearer Token,跟IdToken信息有重疊因谎。這兩個token都可以拿到https://jwt.io里面解開看看基括。具體的描述請參看:Using Tokens with User Pools。
{
"AuthenticationResult": {
"AccessToken": "eyJraWQiOiJicVQ4ZkViVzJCbXN2blZwcGRlUWQ0REhKaTZjdzNNZGhaTzJrN2s3c2w0PSIsImFsZyI6IlJTMjU2In0.eyJzdWIiOiI4NzI2ZmFjZi1jNjNmLTRlNDQtOGM1YS1jOTE5YjdjNTMxMDYiLCJkZXZpY2Vfa2V5IjoiYXAtc291dGhlYXN0LTJfZjY1MjY0NjktNjBhMi00ZWUyLTk5MTMtNzAyYmE3NTllMjdjIiwidG9rZW5fdXNlIjoiYWNjZXNzIiwic2NvcGUiOiJhd3MuY29nbml0by5zaWduaW4udXNlci5hZG1pbiIsImlzcyI6Imh0dHBzOlwvXC9jb2duaXRvLWlkcC5hcC1zb3V0aGVhc3QtMi5hbWF6b25hd3MuY29tXC9hcC1zb3V0aGVhc3QtMl9IbkdrZVh5YUIiLCJleHAiOjE0OTgyMzU4MjEsImlhdCI6MTQ5ODIzMjIyMSwianRpIjoiNjcyMmUyM2EtMmQ4Mi00YTg2LWE1NWYtZjRjNjRjYjZmMTQ2IiwiY2xpZW50X2lkIjoiMXQ4MHNpOWNoMXZvaTBiZHVzbTVjOXN2biIsInVzZXJuYW1lIjoiaHMwMDIifQ.ONnjTQr0Qd2AaKCxfnBKT3TnMu-k8Jf_awBapH2A3QpzSIBBBYo3lQzL20JMP92gFfwho9XQGsUjPwNMfkIl19YZG_8BZSME1Aw6l9LT5Q35pGBiuaq1A82rOGmmfgS35RYQ25YxeF18_vO6e4gYdxvAHMSrK8zIJQvFWV6wQYkRpucphKg7bCrmdW5mJt_QyC64JA3JYuHGW2bkFM7IsTt9eop5igIxQTp7uR8oWsSLeYAsJ2nkAdRkbvVt1XvqNmFCU8iOIF0rtkm6bKGdYQprlxAHvyxFVTVBJt-42UWWGII7YaYQTF8k7Lhzu6HAlU27KzlSZ2279CVGKw2BVQ",
"ExpiresIn": 3600,
"IdToken": "eyJraWQiOiJlaFNtY1pjM1JBdEhGYkVWVFpucFBDNWZTSFwvSW15dUN1cmRHUk0wcUVrST0iLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiI4NzI2ZmFjZi1jNjNmLTRlNDQtOGM1YS1jOTE5YjdjNTMxMDYiLCJhdWQiOiIxdDgwc2k5Y2gxdm9pMGJkdXNtNWM5c3ZuIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJ0b2tlbl91c2UiOiJpZCIsImF1dGhfdGltZSI6MTQ5ODIzMjIyMSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLmFwLXNvdXRoZWFzdC0yLmFtYXpvbmF3cy5jb21cL2FwLXNvdXRoZWFzdC0yX0huR2tlWHlhQiIsInBob25lX251bWJlcl92ZXJpZmllZCI6dHJ1ZSwiY29nbml0bzp1c2VybmFtZSI6ImhzMDAyIiwicGhvbmVfbnVtYmVyIjoiKzg2MTg5MDU4MTgyOTIiLCJleHAiOjE0OTgyMzU4MjEsImlhdCI6MTQ5ODIzMjIyMSwiZW1haWwiOiJjcWZ6am5lQGdtYWlsLmNvbSJ9.eV9osb4FQUAzCf4bDFGH9SHwuelC1v78oenxINihVGZ7aqJ82sozfSPtMMcsjN9sm32RZajoyBkw9Buni_bywwjv5FtVgoLb3aXkSvHxtNrXyT1Ligym2c3NJvsEC2aiVr5DFBIEZieSwdsLajcM5JSk9KYgO5OAiTuIe_TiKom2lfm7-n_uF0b09Z3GuYqHXkvufxJnXzb3gqxeY1_M6g3BqEu3Nta-kGqabzn_-6JsYgDY14jyBwRrydMqUqjfZjjLRgZxHBitWMWz0dp4wrTpHOGktqtVdjhj9m8-p4IXp-za3ADcoBh5QSCX49loHi2Mm45gfFiyEVLC3X4P7Q",
"RefreshToken": "eyJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.VFeqGiKV-fH8uTpoihvbyS7FVcdPGiSQVZzf9CWL6UfD3ucm5RaL_J0Sm6kh_0T86gZJQdO1nZ2BBongemyipzSvrowOTUqnqk5sE-5mTU6VXZYzRevhnm-Gr2sF7o0Dx4IrI8Esjn2K0KMZx2TLGHGAHRvFTG5kmFJNR_80o9VRMXaN1X_1LEuJF58amfj1lMqUq0lWoLmWBb5AaCnfap3DuIBxq_egFTgV-JvhlZaHD9Y6L8RANh6Rv2YunCYdyMs8Dw8H7HZHSm5hSdB1sIh-e1M6PMVX-i0V_3R6_IkU0qnC_0NTQw_MvZFO6psjDKCNejAAbvMDoJO6zJsDVQ._B25kR6-WKz3zzJW.-5Xv72tm6qz-gnm2Ojf5QfSxGqFsvl_DlSqgHbYLaUJJLcjKlQGH1uhSohaivadFKT29cdoRH-rHATCSQuzia1RyiMXfYtF2a2DLv3gErS6Rgd4EyZWvddLTjWi0-QdrXvEp5Ry1P_2jakp7_Ng4vKRuvkm9kDHTeeLdLEwDIBJXNGXvIx7qHLBDaBbcP2O9ayU0vVSM3WdzkaHe2-hCEvaHe5w9ygLrzqEdpxv1MsP1botJcBPiBFIPCt-29EKMLoDNC9PU8jczJuGwqcGINuYt9S9kh6JMLw-rpX6wofX4h_B6uy8zEiN6JhQWIv4incFvJBjK1z5v8N51gcT3U1yzNtkeImiU8R-SWPl2gTp3SxguK_-FxhjBuQOHv8v1n_NMYkKz7PchFv77TVBEVDFmNg0cdB2gMhV2yk8x_HbNK5ttOncpN_sLDR1YML3YwIRjiWAz4cyCM6oAGOkSEFwkFcwqHy8PtLdXH2rxxhopUfGJAAUJdpxWC_NpoJFvrBT20794sUMEBRU9BBudsTargWSDZaycgYJN-VxYmFIfoqkejJt9iFs8XGZpx0Uz8qMxNic7g-Kl2CMtht5dgK-_DTlqity6d3CQe3kVjabmoVEwfniopEo_y_Uv7tICgAMc2ScOjg-YjFO3oKzdeOejlEmXV0EvivtICR-QChlqN-XlvWebwdruX6xkyYVh6Js12cH-V40Ll8PEaBVpIOlDe5hz53feR3X9hKmfbAqSZVp0Uk9fh_MJf7vh3XnHyamnTTpn4f-0q9lzHwbt6iiN4vxhCoePVwzLCl4FZFllO0XwVJJmhjCc9YbsIgV6BANjLjyHo5pmb8FfjrP95m5vJVHjRztNeYkr6njCL1rkNwxeAjXahPLKGyyyuIqEPfejWHIJJ7-HUfuof3SOwDVjXRK4j7rHpCMAVGUCWzffPtN4rFPqGNUHFMtXW2J05ydCXBXdHgA4WdbfYkrwSbSY51wLU_PW9RUubbAf0P9MS680TdyjZNfavy6l9LiMFfkwXAbVb0lFBbFzMzHRKotBdoJcr01RT2Kz8JOlihsFRDqXb-V0Z06Tku63uO23z9Usyxp3am8tnYhlBBrYe0L_cdRgEXqtSBipKchwfojsQh-uPzbzLX95XSMlLdedcSJSicaeT2VZqt8l-nJzXcGWQ9nFZxdzlT_XA-44hS-o8u1OrIvw_OlFyBd1KFAC5KBCu4SskkQWqg9iAH3Rn33mVGJqf8hcuSVKTYQ3YFyD8yvTmZOHYFnPW7Yc7Ecrg0-s4yXL._4s3xxrYlVU-0LPaIB6Auw",
"TokenType": "Bearer"
},
"ChallengeParameters": {}
}
解開IdToken之后财岔,看看里面的iat
和exp
风皿,可以發(fā)現(xiàn)IdToken的過期時間是一個小時。
Identity Pool登錄成功之后得到的信息如下所示匠璧⊥┛睿看起來就是STS token啊。
{
"Credentials": {
"AccessKeyId": "ASIAI46U752A4IDXV2TA",
"Expiration": 1498235294,
"SecretKey": "rj6Kd07s1lbTpRNOXBNdzxxCY56G2jRN26yddHcW",
"SessionToken": "AgoGb3JpZ2luEIP//////////wEaDmFwLXNvdXRoZWFzdC0yIoACNsPwXYx/zmX42sN3HEEHw/cY0yzELJdHTsF+C+HpUnbklUOmxTvgWIQ8/rVnUGWewsSrazIA5idbm4Chb2OAaPDKlGuAfq/ovZZS2HIhMWFBPnWzFggOsDlqe73QVhw96RW8t8dACTuoNEZjAlXPIPk90oZXHRctEiPr/vrzJYWy5M39RxgY3lxKAe3cosbIJhSARxIxuaudueYdC96xxQXSjQMn7sA5VGsjnU9hytgni4sDR0ozFUlfKi7OhuylKTiB5zIWaMmDnyt+SKfoC506RNPH/QNu3PLLqSUgVG6yMov0Eydub6T66lZgkDDYTmwmgKjze0Pd9aVw0qrapyrdBAjZ//////////8BEAAaDDk3ODM0MzM3MDU3NyIMMF7ptJyDwDX5/6gSKrEE3beePMNROAKR1bB54f+xnvo8ZUryymf430PkKHC3Q0oW1+eeBi44F1raX/Bv4tlq6WWK3RlrFl+gPNLeZC/b9xcyJI2q4luMBwYAbqXHKYJxwzlIhXHGjqxf27/01X9ksK3X8nove2y51TK84MHzxQjm4ABQfE2873mSS1YIbTgOBV7jDYn91pal4lXIrUilQIw1GUQ5m+SSHKfbpzwZpWTbnYesrXfWRd59pYaQ6yntat1/La/mZG5i/Dbk+HUOieyAGffMt5OICB75JpUkRjyMo8qNkdc4/nsEvMNTLl1LQdhVL6zmkKdztNZBbn76Uz1cr7u1sOJLCqHKY5P2uNuGvA11YaJN9MGLJwI+VNSGiDD7hT8Sor2bMHd3r9hy+SGAUfyhjPtch5D8tHwYTT/1GyBLyN2ws7ym/dYxHJ+4gpjK78J7VCjdR1BN5amtQTgzrZ9kjS7SkhVPVLxNJK3+GTk6M5asitd1V/BRwpBHtS1LCFqYAGdlOADVl+TKgo15OmATY9aKmwUoYQpZKV9cvk2ferOGCQwfv92F5QSqxGibb0+8/rJF4CIfpneXp2YLRu07FubicyhLa+pWuMJ5IwC2b6pbZho212PIjuuBrlH+TDEKNF6aC7f4RRnk87A/Chsgq32KxUZVgt5MtOr3LPrMmU1hB28yqb0ofabMq14o3vAgY3+SPa5NBWxQxhO/YN+vB9Y4J+I+p0dxb7amWQNzJLuCURUoK8RT0qfbMI7ntMoF"
},
"IdentityId": "ap-southeast-2:65d024cf-f342-4c5d-8ece-7d1736d24633"
}
IAM
User Pool和Identity Pool怎么跟AWS IAM關聯(lián)起來呢夷恍?那就是配置role魔眨。User Pool可以創(chuàng)建group,然后把用戶加入到group里面酿雪,而group可以設置role遏暴。詳細的描述請看文檔:Assigning IAM Roles to Groups。
Identity Pool同樣可以創(chuàng)建和指定角色执虹。
這些角色在AWS IAM里面都可以找到拓挥。但是User Pool和Identity Pool自己并不會出現(xiàn)在IAM的用戶和組里面。
我有一個疑問是袋励,如果一個賬號在User Pool里面的角色是A,然而Identity Pool使用角色是B当叭,那么我在Identity Pool里面登錄了這個賬號茬故,那么他對應的角色是A還是B呢?還是擁有兩個角色所屬權限的交集或并集蚁鳖?
最后的總結
User Pool貌似是配合AWS API Gateway一起使用的磺芭。畢竟OAuth/OIDC這套東西非常成熟和標準,適用于HTTP協(xié)議下醉箕。
A user pool is integrated with an API as a method authorizer that
is applicable for any method. When calling the methods with such
an authorizer enabled, an API client includes in the request
headers the user's identity token provisioned from the user pool.
API Gateway then validates the token to ensure it belongs to the
configured user pool and authenticates the caller before passing
the request to the backend.
To integrate an API with the Amazon Cognito identity provider,
you, as an API developer, create and own a user pool, create an
API Gateway authorizer connected to the user pool, and enable
the authorizer on selected API methods. You must also distribute
to your API client developers the user pool ID, a client ID, and
possibly the associated client secret that are provisioned from the
user pool. The client will need this information to register users
with the user pool, to provide the sign-in functionality, and to have
the user's identity token provisioned from the user pool.
接著去AWS API Gateway里面看看钾腺。我發(fā)現(xiàn)在Authorizers里面可以指定使用Cognito User Pool Authorizer
徙垫。
Identity Pool給的就是STS token,所以可以直接拿去訪問AWS Service放棒。
Amazon Cognito Federated Identities enable you to create unique
identities for your users and federate them with identity providers.
With an identity, you can obtain temporary, limited-privilege AWS
credentials to synchronize data with Amazon Cognito Sync, or
directly access other AWS services.
使用API Gateway
User Pool的id token可以用來調用API Gateway的API姻报。API Gateway可以設置custom authorizer,這是一個User Pool间螟。如果一個id token對應的用戶屬于這個User Pool吴旋,那么拿著id token就可以訪問API。AWS也支持通過Identity Pool的方式來調用API Gateway厢破,這樣做會麻煩一些荣瑟,需要使用API Gateway生成的接口SDK,配合相應的IAM role摩泪,才能調用成功笆焰。
首先在API Gateway復制PetStore這個API。
在
Authorizers
里面創(chuàng)建一個Cognito User Pool Authorizer
见坑,選擇好region和User Pool嚷掠。
- 設置好之后,可以驗證一下id token鳄梅。id token可以從
CognitoYourUserPools-Sample
demo的日志里面獲取叠国。如果id token這個用戶不屬于wla-demo
這個User Pool,那么驗證會失敗戴尸。
- 對
pets
的GET接口設置Authorization粟焊,選擇上面創(chuàng)建好的custom authorizer。
- 發(fā)布接口之后孙蒙。在Postman里面做測試项棠。HTTP Header里面設置
Authorization
為id token即可。如果只是設置一下HTTP Header挎峦,通過curl也可以做到香追,哈哈,用Postman牛刀殺雞了坦胶。
- 如果不設置
Authorization
透典,那么會提示如下錯誤。
對于整個流程下面幾張圖也有比較好的闡述顿苇。
最后簡單總結一下吧峭咒。我覺得User Pool是一個完整的用戶系統(tǒng),實現(xiàn)了OAuth 2.0纪岁,并且支持SAML做SSO凑队。User Pool可以跟API Gateway聯(lián)動起來,方便用戶做一個完整的Serverless應用幔翰。而Identity Pool則支持主流的ID Provider漩氨,包括User Pool西壮,用戶認證之后頒發(fā)STS token,用于訪問AWS自己的服務叫惊。在AWS服務的歸類中款青,Cognito屬于移動服務
這個類目下面。Cognito+API Gateway+Lambda function=Serverless赋访,有這一套體系可都,加上AWS移動相關的SDK和服務,寫一個App是一件非常愜意的事情蚓耽。