Đăng nhập/Đăng ký với Google
Sơ đồ sau đây cho thấy flow Đăng nhập với Google, tuy nhiên chúng ta sẽ chia việc này thành hai trường hợp:
- Kịch bản 1: đó là flow bạn thấy ở dưới, frontend là Vue, Backend là Sails.js, xác thực thực hiện ở một số phần ở cả hai phía.
- Kịch bản 2: Chúng tôi xử lý OAuth2 hoàn toàn trên Frontend và chỉ cho phép call với Backend khi xác thực thành công.
Cấu hình Google OAuth
Trước khi bắt đầu, chúng ta phải đảm bảo Google được cấu hình đúng cho ứng dụng mới của bạn. Truy cập Google API Console để có được thông tin xác thực OAuth 2.0 như Client ID và Client Secret được cả Google và ứng dụng của chúng ta biết đến.
- Đăng nhập vào Google Developer Console
- Nhấp vào Select a Project và chọn New Project trong menu đổ xuống.
- Đặt tên dự án mà bạn muốn, tôi đặt là Google-oauth2, nhấp Create.
- Khi dự án được tạo (mất vài giây), hãy sử dụng lại bộ chọn dự án và chọn dự án mới tạo của bạn.
- Bây giờ bạn phải thêm các API có sẵn. Chọn và mở Library trong menu bên trái.
- Mở và bật Google + API và API Google Analytics
- Mở tab Credentials, nhấp vào Create Credentials và chọn OAuth client ID — Google cũng cung cấp trình hướng dẫn để giúp bạn đưa ra quyết định này nếu bạn muốn sử dụng Google Auth trong một bối cảnh khác.
- Bảng điều khiển API mở ra, nhấp vào Credentials trên Nav bên trái và chuyển sang tab OAuth Consent Screen – cung cấp tên ứng dụng và logo tùy chọn.
- Trên màn hình tiếp theo. Ở mục Application type chọn Web application và đặt tên — Tôi sử dụng Google-oauth2
- Ở mục Authorized JavaScript origins điền http://localhost:8080 và ở mục Authorized redirect URIs thêm http://localhost:8080/callback và nhấp nút Create
- Cuối cùng, một cửa sổ bật lên chứa Client ID và Client Secret, sao chép các giá trị đó, chúng ta sẽ cần chúng trong code của chúng ta.
Tạo Frontend và Trang Login
Chúng tôi đã tạo trang Đăng nhập và Đăng ký mẫu tại đây [github] (https://github.com/Jebasuthan/Vue-Facebook-Google-oAuth).
Build frontend trong src với npm
và npm run serve
sẽ cung cấp trang đích tại đường dẫn sau: localhost:8080/login
Đăng nhập với Facebook/Google
Trong frontend, mở main.js và thay đổi như sau:
1 2 3 4 5 6 7 8 | import GoogleAuth from <span class="token single-quoted-string string">'@/config/google.js'</span> <span class="token keyword">const</span> gauthOption <span class="token operator">=</span> <span class="token punctuation">{</span> clientId<span class="token punctuation">:</span> <span class="token single-quoted-string string">'xxxxxxxxxxx.apps.googleusercontent.com'</span><span class="token punctuation">,</span> scope<span class="token punctuation">:</span> <span class="token single-quoted-string string">'profile email'</span><span class="token punctuation">,</span> prompt<span class="token punctuation">:</span> <span class="token single-quoted-string string">'select_account'</span> <span class="token punctuation">}</span> Vue<span class="token punctuation">.</span><span class="token keyword">use</span><span class="token punctuation">(</span>GoogleAuth<span class="token punctuation">,</span> gauthOption<span class="token punctuation">)</span> |
Khi bạn đã khởi tạo cài đặt googleauth trong vue main.js, trong components đăng nhập, bạn cần thêm sự kiện nhấp để đăng nhập
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <span class="token operator"><</span>template<span class="token operator">></span> <span class="token operator"><</span>div <span class="token keyword">class</span><span class="token operator">=</span><span class="token double-quoted-string string">"signup-buttons"</span><span class="token operator">></span> <span class="token operator"><</span>a href<span class="token operator">=</span><span class="token double-quoted-string string">"#"</span> <span class="token keyword">class</span><span class="token operator">=</span><span class="token double-quoted-string string">"google-signup"</span> @click<span class="token punctuation">.</span>prevent<span class="token operator">=</span><span class="token double-quoted-string string">"loginWithGoogle"</span><span class="token operator">></span> <span class="token operator"><</span>svg xmlns<span class="token operator">=</span><span class="token double-quoted-string string">"http://www.w3.org/2000/svg"</span> width<span class="token operator">=</span><span class="token double-quoted-string string">"18"</span> height<span class="token operator">=</span><span class="token double-quoted-string string">"18"</span> viewBox<span class="token operator">=</span><span class="token double-quoted-string string">"0 0 18 18"</span> aria<span class="token operator">-</span>hidden<span class="token operator">=</span><span class="token double-quoted-string string">"true"</span><span class="token operator">></span><span class="token operator"><</span>title<span class="token operator">></span>Google<span class="token operator"><</span><span class="token operator">/</span>title<span class="token operator">></span><span class="token operator"><</span>g fill<span class="token operator">=</span><span class="token double-quoted-string string">"none"</span> fill<span class="token operator">-</span>rule<span class="token operator">=</span><span class="token double-quoted-string string">"evenodd"</span><span class="token operator">></span><span class="token operator"><</span>path fill<span class="token operator">=</span><span class="token double-quoted-string string">"#4285F4"</span> d<span class="token operator">=</span><span class="token double-quoted-string string">"M17.64 9.2045c0-.6381-.0573-1.2518-.1636-1.8409H9v3.4814h4.8436c-.2086 1.125-.8427 2.0782-1.7959 2.7164v2.2581h2.9087c1.7018-1.5668 2.6836-3.874 2.6836-6.615z"</span><span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>path<span class="token operator">></span><span class="token operator"><</span>path fill<span class="token operator">=</span><span class="token double-quoted-string string">"#34A853"</span> d<span class="token operator">=</span><span class="token double-quoted-string string">"M9 18c2.43 0 4.4673-.806 5.9564-2.1805l-2.9087-2.2581c-.8059.54-1.8368.859-3.0477.859-2.344 0-4.3282-1.5831-5.036-3.7104H.9574v2.3318C2.4382 15.9832 5.4818 18 9 18z"</span><span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>path<span class="token operator">></span><span class="token operator"><</span>path fill<span class="token operator">=</span><span class="token double-quoted-string string">"#FBBC05"</span> d<span class="token operator">=</span><span class="token double-quoted-string string">"M3.964 10.71c-.18-.54-.2822-1.1168-.2822-1.71s.1023-1.17.2823-1.71V4.9582H.9573A8.9965 8.9965 0 0 0 0 9c0 1.4523.3477 2.8268.9573 4.0418L3.964 10.71z"</span><span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>path<span class="token operator">></span><span class="token operator"><</span>path fill<span class="token operator">=</span><span class="token double-quoted-string string">"#EA4335"</span> d<span class="token operator">=</span><span class="token double-quoted-string string">"M9 3.5795c1.3214 0 2.5077.4541 3.4405 1.346l2.5813-2.5814C13.4632.8918 11.426 0 9 0 5.4818 0 2.4382 2.0168.9573 4.9582L3.964 7.29C4.6718 5.1627 6.6559 3.5795 9 3.5795z"</span><span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>path<span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>g<span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>svg<span class="token operator">></span> Google <span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>template<span class="token operator">></span> <span class="token operator"><</span>script<span class="token operator">></span> import router from <span class="token single-quoted-string string">'@/router/router'</span> export <span class="token keyword">default</span> <span class="token punctuation">{</span> name<span class="token punctuation">:</span> <span class="token single-quoted-string string">'login_signup_social'</span><span class="token punctuation">,</span> methods<span class="token punctuation">:</span> <span class="token punctuation">{</span> loginWithGoogle <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> this<span class="token punctuation">.</span><span class="token variable">$gAuth</span> <span class="token punctuation">.</span><span class="token function">signIn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>GoogleUser <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span> <span class="token comment">// on success do something</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'GoogleUser'</span><span class="token punctuation">,</span> GoogleUser<span class="token punctuation">)</span> <span class="token keyword">var</span> userInfo <span class="token operator">=</span> <span class="token punctuation">{</span> loginType<span class="token punctuation">:</span> <span class="token single-quoted-string string">'google'</span><span class="token punctuation">,</span> google<span class="token punctuation">:</span> GoogleUser <span class="token punctuation">}</span> this<span class="token punctuation">.</span><span class="token variable">$store</span><span class="token punctuation">.</span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'setLoginUser'</span><span class="token punctuation">,</span> userInfo<span class="token punctuation">)</span> router<span class="token punctuation">.</span><span class="token function">push</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'/home'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">.</span><span class="token keyword">catch</span><span class="token punctuation">(</span>error <span class="token operator">=</span><span class="token operator">></span> <span class="token punctuation">{</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'error'</span><span class="token punctuation">,</span> error<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator"><</span><span class="token operator">/</span>script<span class="token operator">></span> <span class="token operator"><</span>style<span class="token operator">></span> <span class="token operator"><</span><span class="token operator">/</span>style<span class="token operator">></span> |
Khi chạy giao diện người dùng, sử dụng lệnh npm run serve
sau khi nhấp vào nút Đăng nhập/Đăng ký sử dụng Google, bạn sẽ nhận được accessToken.
Bây giờ bạn đã có accessToken từ Google. Bạn phải pass qua accessToken để backend api có đủ thông tin về người dùng đăng nhập Google’s sử dụng OAuth2Client.
Trong backend SailsJS, mở google-login.js và thay đổi:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token keyword">const</span> <span class="token punctuation">{</span>OAuth2Client<span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token keyword">require</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'google-auth-library'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> client <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">OAuth2Client</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'xxxxxxxxxxxxx.apps.googleusercontent.com'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> ticket <span class="token operator">=</span> await client<span class="token punctuation">.</span><span class="token function">verifyIdToken</span><span class="token punctuation">(</span><span class="token punctuation">{</span> idToken<span class="token punctuation">:</span> inputs<span class="token punctuation">.</span>accessToken<span class="token punctuation">,</span> audience<span class="token punctuation">:</span> <span class="token single-quoted-string string">'xxxxx.apps.googleusercontent.com'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> payload<span class="token operator">=</span> ticket<span class="token punctuation">.</span><span class="token function">getPayload</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token single-quoted-string string">'Google payload is '</span><span class="token operator">+</span><span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span>payload<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">const</span> userid <span class="token operator">=</span> payload<span class="token punctuation">[</span><span class="token single-quoted-string string">'sub'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> let email <span class="token operator">=</span> payload<span class="token punctuation">[</span><span class="token single-quoted-string string">'email'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> let emailVerified <span class="token operator">=</span> payload<span class="token punctuation">[</span><span class="token single-quoted-string string">'email_verified'</span><span class="token punctuation">]</span><span class="token punctuation">;</span> let name <span class="token operator">=</span> payload<span class="token punctuation">[</span><span class="token double-quoted-string string">"name"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> let pictureUrl <span class="token operator">=</span> payload<span class="token punctuation">[</span><span class="token double-quoted-string string">"picture"</span><span class="token punctuation">]</span><span class="token punctuation">;</span> |
Khi bạn đã thực hiện xong, hãy restart và load lại trang login: http://localhost:8080/login
Khi click vào nút Google, Google Auth được thực hiện trên một cửa sổ bật lên riêng biệt cho phép nhập thông tin đăng nhập Google để xác thực ứng dụng:
Sau khi bạn đã cung cấp thông tin đăng nhập Google của mình, frontend hiện chạy logic xác thực sau:
- Kịch bản 1: VueJS login component nhận authorization code từ google và gọi Sails backend trong http://localhost:8080/login. Ở đó authorization code được dùng để truy xuất access_token, refresh_token, id_token và scope. Người dùng được đưa lại giao diện sử dụng Vuex để cuối cùng người dùng đăng nhập vào trang đích.
- Kịch bản 2: Các bước từ Kịch bản 1 chỉ được thực hiện trên giao diện mà không call gì đến backend.
Bạn có thể checkout từ github souce code
Nguồn: https://medium.com/@itjebasuthan_90100/signup-with-google-using-vuejs-11c9d4428250