Skip to content

Instantly share code, notes, and snippets.

@snake575
Last active March 23, 2020 13:18
Show Gist options
  • Save snake575/20671e32728829d8dbeb5fb3b7e8b1c0 to your computer and use it in GitHub Desktop.
Save snake575/20671e32728829d8dbeb5fb3b7e8b1c0 to your computer and use it in GitHub Desktop.
Nuxt auth with Firebase (provider redirect)
// Firebase auth scheme
// https://auth.nuxtjs.org/guide/scheme.html#schemes
import firebase from 'firebase/app'
import 'firebase/auth'
const DEFAULTS = {
appName: undefined,
token_type: 'Bearer',
userinfo_endpoint: `https://identitytoolkit.googleapis.com/v1/accounts:lookup`,
scope: [],
}
export default class FirebaseScheme {
constructor(auth, options) {
this.$auth = auth
this.name = options._name
this.options = Object.assign({}, DEFAULTS, options)
}
get _firebaseApp() {
return firebase.app(this.options.appName)
}
get _firebaseAuth() {
return firebase.auth(this.options.appName)
}
async mounted() {
// Handle callbacks on page load
const redirected = await this._handleCallback()
if (!redirected) return this.$auth.fetchUserOnce()
}
login(provider) {
for (const scope of this.options.scope) provider.addScope(scope)
this._firebaseAuth.signInWithRedirect(provider)
}
async fetchUser() {
// Token is required but not available
const token = this.$auth.getToken(this.name)
if (!token) return
const key = this._firebaseApp.options.apiKey
if (!key) return
if (!this.options.userinfo_endpoint) return
const { users } = await this.$auth.request({
url: this.options.userinfo_endpoint,
method: 'POST',
params: { key },
data: { idToken: token.split(' ')[1] },
})
const user = users[0]
this.$auth.setUser({
uid: user.localId,
...user,
})
}
async _handleCallback() {
// Handle callback only for specified route
if (
this.$auth.options.redirect &&
this.$auth.ctx.route.path !== this.$auth.options.redirect.callback
)
return
// Callback flow is not supported in server side
if (process.server) return
const { user, credential } = await firebase.auth().getRedirectResult()
if (!user) return
// idToken
let token = await user.getIdToken()
// refresh token
let refreshToken = user.refreshToken
if (!token) return
// Append token_type
if (this.options.token_type) token = this.options.token_type + ' ' + token
// Store token
this.$auth.setToken(this.name, token)
// Store refresh token
if (refreshToken) {
if (this.options.token_type)
refreshToken = this.options.token_type + ' ' + refreshToken
this.$auth.setRefreshToken(this.name, refreshToken)
}
// Store provider credential
if (credential) {
this.$storage.setState('provider', credential.toJSON())
}
// Redirect to home
this.$auth.redirect('home', true)
return true // True means a redirect happened
}
}
export default {
// Nuxt autth setup
// https://auth.nuxtjs.org/guide/setup.html#setup
modules: [
'@nuxtjs/axios',
'@nuxtjs/auth'
],
auth: {
// Options
strategies: {
// Firebase auth scheme
firebase: {
_scheme: 'PATH_TO_FIREBASE_SCHEME',
scope: [
'openid',
'profile',
'email',
// ...
],
},
},
},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment