Files
freeCodeCamp/curriculum/challenges/chinese-traditional/06-quality-assurance/advanced-node-and-express/implementation-of-social-authentication.md

4.3 KiB
Raw Blame History

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
589a69f5f9fc0f352b528e70 實現第一種社交登錄 2 301559 implementation-of-social-authentication

--description--

在應用中這種驗證的基本路徑是:

  1. 在用戶點擊按鈕或者鏈接後,進入驗證頁面,通過第三方平臺(如 GitHub來進行用戶驗證。
  2. 需要在路由中調用 passport.authenticate('github'),跳轉至 GitHub 驗證頁面。
  3. 頁面跳轉到 GitHub 上,如果用戶未登錄 GitHub就需要在這裏進行登錄。 登錄成功後,會出現向用戶申請訪問權限的確認頁。
  4. 如果用戶同意訪問,則用戶會回到我們提供的回調地址,帶着 GitHub 那邊提供的用戶信息回到我們的 app 中。
  5. 驗證已完成。我們的應用需要查詢這個用戶是否已經存在。如果是新用戶,那我們需要把用戶信息存儲到數據庫。

在 OAuth 驗證策略中,我們至少需要提供 Client IDClient 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.
*/