Skip to content

Instantly share code, notes, and snippets.

@hfalucas
Last active February 22, 2025 17:12
Show Gist options
  • Save hfalucas/60cb40c62e2e13e6c797f4887e43c8f6 to your computer and use it in GitHub Desktop.
Save hfalucas/60cb40c62e2e13e6c797f4887e43c8f6 to your computer and use it in GitHub Desktop.

Revisions

  1. Helder Lucas revised this gist Aug 6, 2016. 2 changed files with 0 additions and 0 deletions.
    File renamed without changes.
  2. Helder Lucas revised this gist Aug 6, 2016. 8 changed files with 0 additions and 0 deletions.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
    File renamed without changes.
  3. Helder Lucas created this gist Aug 6, 2016.
    45 changes: 45 additions & 0 deletions Authorization.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,45 @@
    export default {
    /*
    access: {
    requiresLogin: true,
    requiredPermissions: ['admin'],
    permissionType: 'AtLeastOne'
    },
    */
    authorize (requiresLogin, requiredPermissions, permissionType) {
    let result = 'authorized'
    let user = JSON.parse(window.localStorage.getItem('auth-user')) || undefined
    let hasPermission = true
    let token = window.localStorage.getItem('token') || undefined
    let loweredPermissions = []
    let permission, i

    if (requiresLogin === true && (token === undefined && user === undefined)) {
    return 'loginIsRequired'
    }

    if ((requiresLogin === true && token !== undefined) && (requiredPermissions === undefined || requiredPermissions.length === 0)) {
    return 'authorized'
    }

    if (requiredPermissions) {
    loweredPermissions = []
    loweredPermissions.push(user.role.toLowerCase())

    for (i = 0; i < requiredPermissions.length; i++) {
    permission = requiredPermissions[i].toLowerCase()

    if (permissionType === 'CombinationRequired') {
    hasPermission = hasPermission && loweredPermissions.indexOf(permission) > -1
    if (hasPermission === false) break
    } else if (permissionType === 'AtLeastOne') {
    hasPermission = loweredPermissions.indexOf(permission) > -1
    if (hasPermission) break
    }
    }
    result = hasPermission ? 'authorized' : 'notAuthorized'
    }

    return result
    }
    }
    58 changes: 58 additions & 0 deletions Login.vue
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,58 @@
    <template>
    <div>
    <form @submit.prevent="authenticate()">
    <label for="">E-mail:</label>
    <input v-model="auth.email" type="email">

    <label for="">Password</label>
    <input v-model="auth.password" type="password">

    <button type="submit">Login</button>
    </form>
    </div>
    </template>

    <script>
    export default {
    data () {
    return {
    auth: { email: '', password: '' },
    user: {},
    }
    },
    methods: {
    /**
    * Attempts to authenticate the user
    *
    * @return {mixed}
    */
    authenticate () {
    let credentials = this.auth
    this.$http.post('http://api.dev/login', credentials).then((response) => {
    /**
    * Now that we successfully retrieved the token and the user information
    * we have a couple of options:
    *
    * 1) Save the token in local storage
    * - Keeps the token saved even when the browser is closed
    * 2) Save the token in session storage
    * - Deletes the token when user closes the browser or even the tab
    * 3) Save the token in a cookie
    *
    * Both local and session storage api are the same so I'll use the local storage
    * for the sake of the example
    *
    */
    window.localStorage.setItem('token', response.data.token)
    window.localStorage.setItem('auth-user', JSON.stringify(response.data.user))
    this.$route.router.go({name: 'example-component'})
    }).catch((errors) => {
    // catch errors
    })
    }
    }
    }
    </script>
    24 changes: 24 additions & 0 deletions RedirectIfAuthenticated.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    export default function RedirectIfAuthenticated (router) {
    /**
    * If the user is already authenticated he shouldn't be able to visit
    * pages like login, register, etc...
    */
    router.beforeEach(({to, next, abort, redirect}) => {
    let token = window.localStorage.getItem('token')
    let user = JSON.parse(window.localStorage.getItem('auth-user'))

    /**
    * Checks if there's a token and the next page name is none of the following
    */
    if ((token) && (to.name === 'login' || to.name === 'register')) {
    // redirects according user role
    router.go({ /*...*/})
    }

    if (!token) {
    // Logout
    }

    next()
    })
    }
    42 changes: 42 additions & 0 deletions UserHasPermissions.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,42 @@
    /**
    * This is where all the authorization login is stored
    */
    import Authorization from './../Services/Authorization'

    export default function UserHasPermissions (router) {
    /**
    * Before each route we will see if the current user is authorized
    * to access the given route
    */
    router.beforeEach(({to, next, abort, redirect}) => {
    let authorized = false
    let user = JSON.parse(window.localStorage.getItem('atiiv.auth-user'))

    /**
    * Remember that access object in the routes? Yup this why we need it.
    *
    */
    if (to.access !== undefined) {
    authorized = Authorization.authorize(
    to.access.requiresLogin,
    to.access.requiredPermissions,
    to.access.permissionType
    )

    if (authorized === 'loginIsRequired') {
    router.go({name: 'login'})
    }

    if (authorized === 'notAuthorized') {
    /**
    * Redirects to a "default" page
    */
    router.go({ /*...*/ })
    }
    }
    /**
    * Everything is fine? Let's to the page then.
    */
    next()
    })
    }
    50 changes: 50 additions & 0 deletions interceptors.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    /**
    * This code block can be directly in your main.js file if you keep it this simple
    * otherwise extract it to its own file and require it in main.js
    *
    * Don't forget that the code below will be executed within every request.
    *
    */

    Vue.http.interceptors.push((request, next) => {
    /**
    * Here we will fecth the token from local storage and
    * attach it (if exists) to the Authorization header on EVERY request.
    */
    let token = window.localStorage.getItem('token')

    if (token) {
    request.headers = request.headers || {}
    request.headers.Authorization = `Bearer ${token}`
    }

    /**
    * Here is where we can refresh the token.
    */
    next((response) => {
    /**
    * If we get a 401 response from the API means that we are Unauthorized to
    * access the requested end point.
    * This means that probably our token has expired and we need to get a new one.
    */
    if (response.status === 401) {
    return Vue.http.get('http://api.dev/refresh-token').then((result) => {
    // Save the new token on local storage
    window.localStorage.setItem('token', result.data.token)

    // Resend the failed request whatever it was (GET, POST, PATCH) and return its resposne
    return Vue.http(request).then((response) => {
    return response
    })
    })
    .catch(() => {
    /**
    * We weren't able to refresh the token so the best thing to do is
    * logout the user (removing any user information from storage)
    * and redirecting to login page
    */
    return router.go({name: 'login'})
    })
    }
    })
    })
    50 changes: 50 additions & 0 deletions main.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    /**
    * Think of this "main.js" file as your application bootstrap.
    */

    import Vue from 'vue'
    import Resource from 'vue-resource'
    import VueRouter from 'vue-router'
    import routes from './routes'
    import middleware from './middleware'

    // Your app mounting point
    import ExampleComponent from './ExampleComponent.vue'

    /**
    * Documentation link for Vue Router
    * http://vuejs.github.io/vue-router/en/index.html
    */
    Vue.use(VueRouter)

    /**
    * Documentation for Vue Resource
    * https://github.com/vuejs/vue-resource
    */
    Vue.use(Resource)

    /**
    * Router Configuration
    *
    * @type {VueRouter}
    */
    var router = new VueRouter({
    hashbang: false,
    history: true
    })


    /**
    * App Routes
    */
    routes(router)

    /**
    * App Middleware
    */
    middleware(router)

    /**
    * Application mount and initialization
    */
    router.start(ExampleComponent, '#app')
    7 changes: 7 additions & 0 deletions middleware.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,7 @@
    import UserHasPermissions from './Middleware/UserHasPermissions'
    import RedirectIfAuthenticated from './Middleware/RedirectIfAuthenticated'

    export default function middleware (router) {
    UserHasPermissions(router)
    RedirectIfAuthenticated(router)
    }
    34 changes: 34 additions & 0 deletions routes.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,34 @@
    export default function routes (router) {
    router.map({
    '/login': {
    name: 'login',
    component: require('./components/Auth/Login.vue')
    },

    '/example-component': {
    name: 'example-component',
    /**
    * vue-routes allow us to create custom objects in the routes files.
    *
    * This "access" object is created by us and will be used to check the
    * current logged in user permissions on every route change.
    */
    access: {
    requiresLogin: true,
    requiredPermissions: ['admin'],
    permissionType: 'AtLeastOne' // options: AtLeastOne, CombinationRequired
    },
    component: require('./components/ExampleComponent.vue')
    },

    '/other-component': {
    name: 'other-component',
    access: {
    requiresLogin: true,
    requiredPermissions: ['admin', 'manager'],
    permissionType: 'AtLeastOne'
    },
    component: require('./components/other-component.vue')
    }
    })
    }