4.3 KiB
id, title, challengeType, forumTopicId, dashedName
id | title | challengeType | forumTopicId | dashedName |
---|---|---|---|---|
589a69f5f9fc0f352b528e70 | 實現第一種社交登錄 | 2 | 301559 | implementation-of-social-authentication |
--description--
在應用中這種驗證的基本路徑是:
- 在用戶點擊按鈕或者鏈接後,進入驗證頁面,通過第三方平臺(如 GitHub)來進行用戶驗證。
- 需要在路由中調用
passport.authenticate('github')
,跳轉至 GitHub 驗證頁面。 - 頁面跳轉到 GitHub 上,如果用戶未登錄 GitHub,就需要在這裏進行登錄。 登錄成功後,會出現向用戶申請訪問權限的確認頁。
- 如果用戶同意訪問,則用戶會回到我們提供的回調地址,帶着 GitHub 那邊提供的用戶信息回到我們的 app 中。
- 驗證已完成。我們的應用需要查詢這個用戶是否已經存在。如果是新用戶,那我們需要把用戶信息存儲到數據庫。
在 OAuth 驗證策略中,我們至少需要提供 Client ID 和 Client Secret,這樣第三方平臺就會獲悉驗證請求的來源,以及這個來源是否有效。 爲此,需要去我們使用的第三方驗證平臺(比如 GitHub)獲取這兩個字段的值。 注意,我們獲取到的這個值是唯一的,僅對我們的當前 app 有效——因此,千萬不要分享給別人,更不要上傳到公共倉庫或者直接寫在代碼裏。 通常,我們會把它們放在 .env
文件裏,並通過 process.env.GITHUB_CLIENT_ID
獲取。 對於這次挑戰,我們將會使用 GitHub 作爲驗證平臺。
首先,你需要進入賬戶設置裏的 “developer settings(開發者設置)”板塊,在 'OAuth applications' 獲取 Client ID and Secret。 點擊 “Register a new application(註冊一個新的應用)”,設置你的應用名稱,然後把你的 Replit 主頁地址(不是項目代碼的 url)粘貼到 Homepage URL。然後,回調 url 需要設置成上面 Homepage URL 裏你粘貼的地址,但後面要加上 /auth/github/callback
。 這樣在用戶通過 Github 驗證後才能跳轉到我們指定的頁面。 在你的 .env
文件裏將返回的信息保存爲 'GITHUB_CLIENT_ID'
和 'GITHUB_CLIENT_SECRET'
。
在你的 routes.js
文件中,添加 showSocialAuth: true
到主頁路由,在 showRegistration: true
的後面。 然後,爲 /auth/github
和 /auth/github/callback
創建兩個接收 GET 請求的路由。 第一個只需要通過調用 passport 來驗證 'github'
。 第二個應該調用 passport 來驗證 'github'
,但需要在失敗時跳轉回主頁 /
,成功時跳轉到用戶頁面 /profile
(跳轉的邏輯與上一個項目中的邏輯一樣)。
例如 /auth/github/callback
應該像我們處理在上一個項目中正常的登錄一樣:
app.route('/login')
.post(passport.authenticate('local', { failureRedirect: '/' }), (req,res) => {
res.redirect('/profile');
});
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考這裏的答案。
--hints--
路由 /auth/github 應正確配置。
(getUserInput) =>
$.get(getUserInput('url') + '/_api/routes.js').then(
(data) => {
assert.match(
data.replace(/\s/g, ''),
/('|")\/auth\/github\/?\1[^]*?get.*?passport.authenticate.*?github/gi,
'Route auth/github should only call passport.authenticate with github'
);
},
(xhr) => {
throw new Error(xhr.statusText);
}
);
路由 /auth/github/callback 應正確配置。
(getUserInput) =>
$.get(getUserInput('url') + '/_api/routes.js').then(
(data) => {
assert.match(
data.replace(/\s/g, ''),
/('|")\/auth\/github\/callback\/?\1[^]*?get.*?passport.authenticate.*?github.*?failureRedirect:("|')\/\2/gi,
'Route auth/github/callback should accept a get request and call passport.authenticate for github with a failure redirect to home'
);
},
(xhr) => {
throw new Error(xhr.statusText);
}
);
--solutions--
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/