Triển khai OAuth với Node.js và Github

Nội dung bài viết

Triển khai OAuth với Node.js và Github OAuth với Node.js và Github trong bài viết KÈM SOURCE này thì chúng ta sẽ biết thêm một cách triển khai login với github. Chính vì cơ chế của github rất tiện lợi nên việc viết code cũng không phức tạp như nhiều người từng nghĩ. Và đương nhiên rồi, việc thực hiện được ví dụ này các bạn ít nhất phải biết cơ bản về OAuth là gì? Vì sao lại triển khai với Nodejs thì có cần tôi giải thích về Node nữa không khi có hơn 50 bài viết về NodeJS rồi.

À chú ý nè, ở bài viết "xác thực SMS free với Firebase" thì tôi có làm 4 demo trong đó có login với facebook, google, sms, và github, nếu như bạn không muốn sử dụng firebase và đưa về Nodejs thì đây có lẽ là điều đúng đắn nhất.

Ngoài ra nắm vững cách triển khai và cài đặt của một ứng dụng Nodejs. Một vài lời cho các bạn của tôi. Còn bây giờ thì đi vào vấn đề thôi. Có thể nó hơi dài, vì tôi phải giải thích cặn kẽ từng bước cho các bạn. Nếu bạn nào cảm thấy chỉ cần xem Source Code thôi thì có thể, kéo xuống dưới bài viết, tôi để LINK ở đó.


Register a Github OAuth App


Đương nhiên rồi, bạn phải có tài khoản ở github rồi sau đó truy cập vào Github OAuth Apps. Và đây là giao diện sau khi các bạn đi qua đó, ở đây tôi đã chụp lại cho các bạn có cái nhìn tổng quan nhất. 

Trong mục này, chỉ có một mục quan trọng nhất đó là Authorization callback URL, ở đó các bạn nhập Link mà ở đây của tôi là http://localhost:3000/github/callback - Đây sẽ là URL mà Github sẽ gửi mã ủy quyền sau khi ủy quyền hoàn tất Sau khi bạn Register thành công thì giao diện tiếp theo sẽ là App's Client Id and Secret. Tôi cũng đã chụp cho các bạn. 

Và ở đây bạn cần chú ý đến clientId clientSecret nó sẽ được sử dụng trong ứng dụng Nodejs của chúng ta.


Setup project Nodejs Login


Bước này thì chúng ta triển khai một dự án Login Nodejs, nếu các bạn muốn cấu hình một dự án hoàn chỉnh thì trước đây tôi có đưa ra một "Express và Node.Js xây dựng cấu trúc một dự án chuẩn" thì các bạn có thể dựa vào đó để setup chuẩn ngay từ lúc đầu. Và đây là code của dự án, tôi chỉ giải thích những chỗ quan trọng, còn basic thì thôi nhé. Có gì cứ comment là tôi giải đáp liền. Thật ra nói cho oai vậy thôi, chứ quan trọng nhất là Login_Controller à.

const clientID = 'xxxxxx';
const clientSecret = 'xxxxxxxxx';
const axios = require('axios')

var self = module.exports = {
    callback: async (req, res) => {
        try {
            const {code} = req.query.code;

            // axios({
            //     method: 'post',
            //     url: `https://github.com/login/oauth/access_token?client_id=${clientID}&client_secret=${clientSecret}&code=${code}`,
            //     headers: {
            //         accept: 'application/json'
            //     }
            // }).then((response) => {
            //     access_token = response.data.access_token
            //     res.redirect('/success');
            // })

            //async await 
            const resp = await axios.post(`https://github.com/login/oauth/access_token?client_id=${clientID}&client_secret=${clientSecret}&code=${code}`, {}, {
                headers: {
                    accept: 'application/json'
                }
              });
            console.log(':::', resp.data);
            const {access_token} = resp.data;
            if(access_token){
                const resp = await axios.get(`https://api.github.com/user`, {
                    headers: {
                      'Authorization': `token ${access_token}`
                    }
                });
                return res.render('success',{ userData: resp.data });
            }

            // axios({
            //     method: 'get',
            //     url: `https://api.github.com/user`,
            //     headers: {
            //       Authorization: 'token ' + access_token
            //     }
            //   }).then((response) => {
            //     res.render('pages/success',{ userData: response.data });
            //   })

        } catch (error) {
            console.error(`Error`);
        }
    }
}

Trên kia có nói đến việc lấy clientID và clientSecret. Sau khi lấy về các bạn khai báo như sau:

const clientID = 'xxxxxx';
const clientSecret = 'xxxxxxxxx';

Đoan này có nghĩa là gì:

const {code} = req.query.code;

Code đây chính là hệ thống github sẽ gửi code này trên link mà chúng ta nói ở trên chính là Authorization callback URL cụ thể là : http://localhost:3000/github/callback. Sau khi chũng ta có lấy được Code rồi thì bước tiếp theo lấy access_token. Vì sao lại phải lấy token, và access_token quan trọng như thế nào thì tôi đã có bài viết về nó rồi, bạn có thể đọc để tìm hiểu hơn ở bài viết "Tìm hiểu về Token, access token và refresh token là gì?".. Sau khi có token rồi thì việc lấy Userinfo thì quá dễ. Các bạn có thể xem code:

 const resp = await axios.get(`https://api.github.com/user`, {
      headers: {
        'Authorization': `token ${access_token}`
      }
  });
  return res.render('success',{ userData: resp.data });

Ở file trên tôi triển khai hai cách, một là dùng callback, và hai là dùng async-await. Bạn nào cảm thấy phù hợp thì có thể sử dụng theo cách mình mong muốn. Và chú ý về cách set header trong axios nhé.


SourceCode Login github with nodejs

Hình ảnh login của ví dụ:

login nodejs github

Hình ảnh sau khi Login thành công:

Vậy là xong, đây là 1 trong 4 cơ chế đăng nhập mà mỗi lập trình viên phải biết hiện nay. Các bạn quan tâm hoặc cần code tham khảo có thể download tại: SourceCode github

Thanks!

Có thể bạn đã bị missing