From 9b09459c16dc2e913d4178a452f2264950f449f9 Mon Sep 17 00:00:00 2001 From: Joel Schneider Date: Sat, 28 Apr 2018 05:46:37 -0400 Subject: [PATCH] feat: laravel passport provider (#157) --- docs/SUMMARY.md | 1 + docs/providers/passport.md | 32 +++++++++++++ lib/providers/laravel.passport.js | 79 +++++++++++++++++++++++++++++++ lib/schemes/oauth2.js | 1 + 4 files changed, 113 insertions(+) create mode 100644 docs/providers/passport.md create mode 100644 lib/providers/laravel.passport.js diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index e21cef9f5..6fb8804fd 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -14,6 +14,7 @@ * [Facebook](providers/facebook.md) * [Github](providers/github.md) * [Google](providers/google.md) + * [Laravel Passport](providers/passport.md) * API * [Auth](api/auth.md) * [Storage](api/storage.md) diff --git a/docs/providers/passport.md b/docs/providers/passport.md new file mode 100644 index 000000000..f2529fc36 --- /dev/null +++ b/docs/providers/passport.md @@ -0,0 +1,32 @@ +# Laravel Passport + +[Source Code](https://github.com/nuxt-community/auth-module/blob/dev/lib/providers/passport.js) + +## Usage + +```js +auth: { + strategies: { + 'laravel.passport': { + url: '...', + client_id: '...', + client_secret: '...' + }, + } +} +``` + +## Usage + +Anywhere in your application logic: + +```js +this.$auth.loginWith('passport') +``` + +💁 This provider is based on [oauth2 scheme](../schemes/oauth2.md) and supports all scheme options. + +### Obtaining `url`, `client_id` and `client_secret` + +These options are **REQUIRED**. The `url` is the location of your Laravel application. To obtain the `client_id` and `client_secret`, create a new client app in your [Laravel app](https://laravel.com/docs/5.6/passport#managing-clients). + diff --git a/lib/providers/laravel.passport.js b/lib/providers/laravel.passport.js new file mode 100644 index 000000000..765348d19 --- /dev/null +++ b/lib/providers/laravel.passport.js @@ -0,0 +1,79 @@ +const axios = require('axios') +const bodyParser = require('body-parser') +const { assignDefaults } = require('./_utils') + +module.exports = function laravelPassport (strategy) { + assignDefaults(strategy, { + _scheme: 'oauth2', + _name: 'laravel.passport', + authorization_endpoint: `${strategy.url}/oauth/authorize`, + token_endpoint: `${strategy.url}/oauth/token`, + token_key: 'access_token', + token_type: 'Bearer', + response_type: 'code', + grant_type: 'authorization_code', + scope: '*' + }) + + // Get client_secret, client_id and token_endpoint + const clientSecret = strategy.client_secret + const clientID = strategy.client_id + const tokenEndpoint = strategy.token_endpoint + + // IMPORTANT: remove client_secret from generated bundle + delete strategy.client_secret + + // Endpoint + const endpoint = `/_auth/oauth/${strategy._name}/authorize` + strategy.access_token_endpoint = endpoint + + // Set response_type to code + strategy.response_type = 'code' + + // Form parser + const formMiddleware = bodyParser.urlencoded() + + // Register endpoint + this.options.serverMiddleware.unshift({ + path: endpoint, + handler: (req, res, next) => { + if (req.method !== 'POST') { + return next() + } + + formMiddleware(req, res, () => { + const { + code, + redirect_uri: redirectUri = strategy.redirect_uri, + response_type: responseType = strategy.response_type, + grant_type: grantType = strategy.grant_type + } = req.body + + if (!code) { + return next() + } + + axios + .request({ + method: 'post', + url: tokenEndpoint, + data: { + client_id: clientID, + client_secret: clientSecret, + grant_type: grantType, + response_type: responseType, + redirect_uri: redirectUri, + code + }, + headers: { + Accept: 'application/json' + } + }) + .then(response => { + res.end(JSON.stringify(response.data)) + }) + .catch(error => next(error)) + }) + } + }) +} diff --git a/lib/schemes/oauth2.js b/lib/schemes/oauth2.js index 9bef344fd..6e21a5954 100644 --- a/lib/schemes/oauth2.js +++ b/lib/schemes/oauth2.js @@ -99,6 +99,7 @@ export default class Oauth2Scheme { const data = await this.$auth.request({ method: 'post', url: this.options.access_token_endpoint, + baseURL: false, data: encodeQuery({ code: parsedQuery.code, client_id: this.options.client_id,