├── LICENSE ├── README.md ├── index.js ├── package.json └── sample.html /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 simmatrix 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-google-oauth 2 | Handling Google sign-in and sign-out for Vue.js applications 3 | 4 | Forked from https://github.com/simmatrix/vue-google-auth 5 | 6 | Same as fork but allows you to override options and a few other bug fixes. 7 | 8 | ## Installation 9 | ``` 10 | npm install vue-google-oauth 11 | ``` 12 | 13 | ## Initialization 14 | ``` 15 | import GoogleAuth from 'vue-google-oauth' 16 | 17 | Vue.use(GoogleAuth, { client_id: 'xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com' }) 18 | Vue.googleAuth().load() 19 | ``` 20 | Ideally you shall place this in your app entry file, e.g. src/main.js 21 | 22 | ## Usage - Sign-in 23 | ### (a) Handling Google sign-in, getting the one-time authorization code from Google 24 | ``` 25 | import Vue from 'vue' 26 | 27 | Vue.googleAuth().signIn(function (authorizationCode) { 28 | 29 | // things to do when sign-in succeeds 30 | 31 | // You can send the authorizationCode to your backend server for further processing, for example 32 | this.$http.post('http://your/backend/server', { code: authorizationCode, redirect_uri: 'postmessage' }).then(function (response) { 33 | if (response.body) { 34 | // ... 35 | } 36 | }, function (error) { 37 | console.log(error) 38 | }) 39 | 40 | }, function (error) { 41 | // things to do when sign-in fails 42 | }) 43 | ``` 44 | 45 | The `authorizationCode` that is being returned is the `one-time code` that you can send to your backend server, so that the server can exchange for its own access token and refresh token. 46 | 47 | 48 | ### (b) Alternatively, if you would like to directly get back the access_token and id_token 49 | ``` 50 | import Vue from 'vue' 51 | 52 | // Just add in this line 53 | Vue.googleAuth().directAccess() 54 | 55 | Vue.googleAuth().signIn(function (googleUser) { 56 | // things to do when sign-in succeeds 57 | }, function (error) { 58 | // things to do when sign-in fails 59 | }) 60 | ``` 61 | 62 | The `googleUser` object that is being returned will be: 63 | ``` 64 | { 65 | "token_type": "Bearer", 66 | "access_token": "xxx", 67 | "scope": "xxx", 68 | "login_hint": "xxx", 69 | "expires_in": 3600, 70 | "id_token": "xxx", 71 | "session_state": { 72 | "extraQueryParams": { 73 | "authuser": "0" 74 | } 75 | }, 76 | "first_issued_at": 1234567891011, 77 | "expires_at": 1234567891011, 78 | "idpId": "google" 79 | } 80 | ``` 81 | 82 | ## Usage - Sign-out 83 | Handling Google sign-out 84 | ``` 85 | import Vue from 'vue' 86 | 87 | Vue.googleAuth().signOut(function () { 88 | // things to do when sign-out succeeds 89 | }, function (error) { 90 | // things to do when sign-out fails 91 | }) 92 | ``` 93 | 94 | ## Additional Help 95 | Do refer to this [sample login page HTML file](https://github.com/TinyNova/vue-google-auth/blob/master/sample.html). 96 | 97 | If you are curious of how the entire Google sign-in flow works, please refer to the diagram below 98 | ![Google Sign-in Flow](http://i.imgur.com/BQPXKyT.png) 99 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | ;(function (global, factory) { 2 | if (typeof define === 'function' && define.amd) { 3 | define([], factory) 4 | } else if (typeof exports === 'object') { 5 | module.exports = factory() 6 | } else { 7 | global.Index = factory() 8 | } 9 | }(this, function () { 10 | var config = null 11 | var directAccess = false 12 | var gapiUrl = 'https://apis.google.com/js/api:client.js' 13 | 14 | var gAuth = { 15 | install: function (Vue, options) { 16 | Vue.googleAuth = googleAuth 17 | Vue.prototype.$googleAuth = googleAuth 18 | 19 | if (typeof options === 'object') { 20 | config = Object.assign({ scope: 'profile email https://www.googleapis.com/auth/plus.login' }, options) 21 | } 22 | } 23 | } 24 | 25 | function googleAuth () { 26 | return { 27 | load: function () { 28 | return new Promise(function (resolve, reject) { 29 | if (window.gapi === undefined) { 30 | installClient().then(function () { 31 | return initClient() 32 | }).then(function () { 33 | resolve() 34 | }) 35 | } else if (window.gapi !== undefined && window.gapi.auth2 === undefined) { 36 | initClient().then(function () { 37 | resolve() 38 | }) 39 | } 40 | }) 41 | }, 42 | 43 | directAccess: function () { 44 | directAccess = true 45 | }, 46 | 47 | signIn: function (successCallback, errorCallback) { 48 | if (directAccess) { 49 | window.gapi.auth2.getAuthInstance().signIn().then(function (googleUser) { 50 | successCallback(googleUser) 51 | }, function (error) { 52 | errorCallback(error) 53 | }) 54 | } else { 55 | window.gapi.auth2.getAuthInstance().grantOfflineAccess({'redirect_uri': 'postmessage'}).then(function (response) { 56 | successCallback(response.code) 57 | }, function (error) { 58 | errorCallback(error) 59 | }) 60 | } 61 | }, 62 | 63 | signOut: function (successCallback, errorCallback) { 64 | window.gapi.auth2.getAuthInstance().signOut().then(function () { 65 | successCallback() 66 | }, function (error) { 67 | errorCallback(error) 68 | }) 69 | } 70 | } 71 | } 72 | 73 | function installClient () { 74 | return new Promise(function (resolve, reject) { 75 | var script = document.createElement('script') 76 | script.src = gapiUrl 77 | script.onreadystatechange = script.onload = function () { 78 | if (!script.readyState || /loaded|complete/.test(script.readyState)) { 79 | setTimeout(function () { 80 | resolve() 81 | }, 500) 82 | } 83 | } 84 | document.getElementsByTagName('head')[0].appendChild(script) 85 | }) 86 | } 87 | 88 | function initClient () { 89 | return new Promise(function (resolve, reject) { 90 | window.gapi.load('auth2', function () { 91 | window.gapi.auth2.init(config) 92 | resolve() 93 | }) 94 | }) 95 | } 96 | 97 | return gAuth 98 | })) 99 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-google-oauth", 3 | "version": "1.0.5", 4 | "description": "Handling Google sign-in and sign-out", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/TinyNova/vue-google-oauth.git" 12 | }, 13 | "keywords": [ 14 | "vue", 15 | "google", 16 | "authentication", 17 | "gapi", 18 | "signin", 19 | "signout", 20 | "login", 21 | "logout" 22 | ], 23 | "author": "Simmatrix Labs, Britton Mathews", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/TinyNova/vue-google-oauth/issues" 27 | }, 28 | "homepage": "https://github.com/TinyNova/vue-google-oauth#readme" 29 | } 30 | -------------------------------------------------------------------------------- /sample.html: -------------------------------------------------------------------------------- 1 | 13 | 14 | 81 | 82 | 91 | --------------------------------------------------------------------------------