nuxt-community / auth-module

Zero-boilerplate authentication support for Nuxt 2
https://auth.nuxtjs.org
MIT License
1.93k stars 925 forks source link

I want to make a custom scheme with local strategies #1446

Closed abodojustin closed 2 years ago

abodojustin commented 2 years ago

I want to make a custom scheme with local strategies but I don't know how can I do it using customScheme. Documentation of nuxt/auth v5 doest not help me

I want to execute two endpoint:

1- request

POST /oauth/v2/token
HEAD: 
  Content-Type: application/x-www-form-urlencoded

body of the request:

clientId : string
clientSecret: string
grantType: string
username: string
password: string

response:

{
  "accessToken": "string",
  "expireTime": "2022-01-10T20:29:10.721Z",
  "refreshToken": "string"
}

2- request

GET /security/users/me
HEAD 
  x-locale: fr|en
  authorization: Bearer <TOKEN>

response:

{
  "username": "string",
  "firstname": "string",
  "lastname": "string",
  "email": "string",
  "phone": "string",
  "locale": "fr",
  "id": 1,
  "enabled": true,
  "createdAt": "2022-01-10T20:38:36.478Z",
  "updatedAt": "2022-01-10T20:38:36.478Z",
  "expiresAt": "2022-01-10T20:38:36.478Z",
  "loggedAt": "2022-01-10T20:38:36.478Z",
  "roles": [
    {
      "name": "string",
      "description": "string",
      "code": "string",
      "id": 1,
      "enabled": true,
      "createdAt": "2022-01-10T20:38:36.478Z",
      "updatedAt": "2022-01-10T20:38:36.478Z",
      "translations": {
        "fr": {
          "name": "string",
          "description": "string"
        },
        "en": {
          "name": "string",
          "description": "string"
        }
      },
      "permissions": [
        {
          "id": 1,
          "code": "string",
          "endUI": {
            "name": "string",
            "title": "string",
            "id": 1,
            "code": "string",
            "type": {
              "name": "string",
              "code": "string",
              "id": 1,
              "enabled": true,
              "createdAt": "2022-01-10T20:38:36.478Z",
              "updatedAt": "2022-01-10T20:38:36.478Z",
              "translations": {
                "fr": {
                  "name": "string"
                },
                "en": {
                  "name": "string"
                }
              }
            },
            "module": {
              "name": "string",
              "description": "string",
              "code": "string",
              "id": 1,
              "enabled": true,
              "createdAt": "2022-01-10T20:38:36.478Z",
              "updatedAt": "2022-01-10T20:38:36.478Z",
              "translations": {
                "fr": {
                  "name": "string",
                  "description": "string"
                },
                "en": {
                  "name": "string",
                  "description": "string"
                }
              }
            },
            "icon": "string",
            "uri": "string",
            "translations": {
              "fr": {
                "name": "string",
                "title": "string"
              },
              "en": {
                "name": "string",
                "title": "string"
              }
            }
          }
        }
      ]
    }
  ],
  "avatar": {
    "id": 1,
    "url": "string"
  }
}

nuxt.config.js

    modules: [
        // https://go.nuxtjs.dev/axios
        '@nuxtjs/axios',
        // https://go.nuxtjs.dev/pwa
        '@nuxtjs/pwa',

        '@nuxtjs/auth-next',

        '@nuxtjs/dotenv',

        '@nuxtjs/i18n', [
            'nuxt-vuex-localstorage',
            {
                mode: 'debug',
                localStorage: [
                    'user',
                    'service',
                    'location',
                    'storeType',
                    'warehouse',
                    'openingRange',
                    'store',
                    'holiday',
                    'taxon',
                    'provider',
                    'productOption',
                    'productAttribute',
                    'product',
                    'productVariant',
                    'glassesCatalog'
                ],
            },
        ],
    ],
router: {
        middleware: ['auth']
    },
    // Auth Strategies
    auth: {
        strategies: {
            customStrategy: {
            _scheme: '~/schemes/customScheme',
            endpoints: {
                login: { 
                headers: { 
                    'Content-Type': 'application/x-www-form-urlencoded' 
                }, 
                url: '/oauth/v2/token', 
                method: 'post' 
                },
                user: { 
                url: '/security/users/me', 
                method: 'get',
                propertyName: '',
                headers: {
                    'x-locale': 'fr',
                    'Authorization': `Bearer ${It should be a token (accessToken) for the first request}`
                }                 
                }
            }
            }
        }
    }

~/schemes/customeScheme.js


import { LocalScheme } from '~auth/runtime'

export default class CustomScheme extends LocalScheme {
  // Override `fetchUser` method of `local` scheme
  async fetchUser (endpoint) {
    // Token is required but not available
    if (!this.check().valid) {
      return
    }

    // User endpoint is disabled.
    if (!this.options.endpoints.user) {
      this.$auth.setUser({})
      return
    }

    // Try to fetch user and then set
    return this.$auth.requestWith(
      this.name,
      endpoint,
      this.options.endpoints.user
    ).then((response) => {
      const user = getProp(response.data, this.options.user.property)

      // Transform the user object
      const customUser = {
        ...user,
        fullName: user.firstName + ' ' + user.lastName,
        roles: ['user']
      }

      // Set the custom user
      // The `customUser` object will be accessible through `this.$auth.user`
      // Like `this.$auth.user.fullName` or `this.$auth.user.roles`
      this.$auth.setUser(customUser)

      return response
    }).catch((error) => {
      this.$auth.callOnError(error, { method: 'fetchUser' })
    })
  }
}

~/login.vue

onSubmit(){
      this.isSubmitting = true;
      this.isDisabled= true;
      let formData = new FormData();
      formData.append("clientId", process.env.CLIENT_ID);
      formData.append("clientSecret", process.env.CLIENT_SECRET);
      formData.append("grantType", "password");
      formData.append("username", this.dataUser.username);
      formData.append("password", this.dataUser.password);

      this.$refs.dataUser.validate(async (valid, fieldsError) => {
         this.validate = valid; 
         if(valid){
            try {
            let response =  await this.$auth.loginWith('customStrategy', { data: formData })
            console.log(response);
            this.$store.dispatch('storeSecurity/storeUserToken', response.data);
          } catch (error) {
            this.$message.error({content: this.$t("login.error"), key, duration: 3}); 

          }
        }
      });
    },

If I want to fetch user, how can i do please ???

abodojustin commented 2 years ago

please @bmulholland can you help me ?

bmulholland commented 2 years ago

Sorry, I don't have time to help with individual cases. If you figure it out and have info that should be in the documentation, please write that up to help people in future.