Overview
nuxt-saasmvp-oauth is a Nuxt 3 Module employing the OAuth 2.0 authorization framework defined by IETF RFC 6749 to obtain limited access to a HTTP service. Access to protected resources is granted to Users and REST API Endpoints using an access token conforming with the IETF RFC 7519 JSON Web Token (JWT) standard. The module may be used within the saasmvp framework ecosystem or with any Nuxt 3 application. nuxt-saasmvp-oauth is lightweight and easy to use for fast deployment.
Implicit Authorization Grant
An authorization grant is a credential used to obtain a JWT access token by either a User or REST API Endpoint to access protected resources. nuxt-saasmvp-oauth
employs the implicit authorization grant type, a simplified authorization protocol flow optimized for use with a browser. Using an implicit authorization grant type, the browser is issued an access token directly.
JWT Access Token
The use of JWT as an OAuth access token allows stateless sessions to exist between the browser and the server. This approach eliminates the need for traditional authentication mechanisms using cookies, resulting in a much simpler authentication scheme. The use of Nuxt 3 composables for state management allows for the persistent storage of the access token for use by the Nuxt 3 client and server application. Since client side data is subject to tampering, JWT provides a security mechanism using signatures and encryption. The signature is used to validate the access token from tampering while encryption is used to protect the access token from being read by unauthorized users.
About Refresh Tokens
Refresh tokens are credentials used to obtain a new access token when the current access token becomes invalid or expires. Issuing a refresh token is optional and has not been implemented in the nuxt-saasmvp-oauth
module. The access token simply expires. It is the responsibility of the Nuxt 3 application to handle this expiry using the available module functions.
User Authentication
The nuxt-saasmvp-oauth
module can be used for either or both User and API Authentication. The module can be used on its own with any Nuxt 3 development effort or with the saasmvp ecosystem
. Figure 1 provides a high level overview of User Authentication.
User Authentication can be broadly seperated into three parts: 1) User Navigation, 2) The Nuxt 3 Client (Browser) with the associated nuxt-saasmvp-oauth
client function smvpGetOAuthToken
plus smvp-pageauth
client middleware that utilizes the smvpGetOAuthAuthorization
client function; and 3) The Nuxt 3 Server containing the saasmvp Authorization Server
with two internal REST API Endpoints, smvp-user-token
and smvp-authorize
.
The User will first access an
Unprotected Page
to provide login credentials to thesmvpGetOAuthToken
client function in order to receive aJWT Access Token
. This function will send an OAuth Implicit Authorization Grant request using HTTP(S) to thesaasmvp Authorization Server's
smvp-user-token
endpoint.The
JWT Access Token
will be returned in a HTTP(S) response to thesmvpGetOAuthToken
client function. TheJWT Access Token
will be made available in theuseAuth
composable.Any
Protected Page
requires the Nuxt 3definePageMeta
compiler macro including the named route middleware directive specifyingsmvp-pageauth
. When aProtected Page
is navigated to, thesmvp-pageauth
client middleware reads theJWT Access Token
from theuseAuth
composable and sends the JWT Access Token Validation HTTP(S) request to thesaasmvp Authorization Server's
smvp-authorize
endpoint for authentication.The
JWT Access Token Validation Status
HTTP(S) response is returned to thesmvp-pageauth
client middleware.If the
JWT Access Token
is valid, thesmvp-pageauth
client middleware permits navigation to theProtected Page
. Otherwise, the User is redirected to theRedirected Page
specified in thesmvpInitAuth
redirectRoute
parameter.
REST API Endpoint Authentication
A high level view of REST API Endpoint Authentication is illustrated in Figure 2 API Authentication.
REST API Endpoint Authentication can be broken down into two major parts: 1) The Nuxt 3 Client (Browser) nuxt-saasmvp-oauth
module client function smvpGetOAuthApiKey
plus associated developer defined REST API Endpoint requests; and 2) The Nuxt 3 Server including the smvp-apiauth
server middleware plus the saasmvp Authorization Server
with the companion smvp-api-token
internal REST API Endpoint.
An end User of the developer defined REST API Endpoint(s) receives a
JWT Access Token
(i.e. Bearer Token) by calling thenuxt-saasmvp-oauth
module client functionsmvpGetOAuthApiKey
. An OAuth Implicit Authorization Grant request is sent to thesmvp-apiauth
server middleware which is forwarded to thesaasmvp Authorization Server
smvp-api-token
internal REST API Endpoint.A
JWT Access Token
with a long-lived expiration time is returned to the end User of the developer defined REST API Endpoint(s). TheJWT Access Token
contains a unique identifier such as the end User's account number to bind theJWT Access Token
to the end User. TheJWT Access Token
is subsequently made available in the X-TOKEN Header of the developer defined REST API Endpoint(s) request. TheJWT Access Token
should be stored by the developer on behalf of the end User for subsequent access to the developer defined REST API Endpoint(s).Every developer defined REST API Endpoint HTTP(S) request is checked by the
smvp-apiauth
server middleware to determine if the requested route isprotected
. If the route is NOT protected, the request is forwarded to the developer defined REST API Endpoint without authentication. Otherwise, the route is protected and thesmvp-apiauth
server middleware checks if theJWT Access Token
supplied in the X-TOKEN HTTP(S) request Header is valid. Thesmvp-apiauth
server middleware sets an internal composable,useRestAuth
totrue
if theJWT Access Token
is valid, otherwise the composableuserRestAuth
is set tofalse
. The state of theuserRestAuth
composable is read only and can be accessed by using thesmvpIsRestAuth
function inside the developer defined REST API Endpoint.Should the route be unprotected, the developer defined REST API Endpoint returns a HTTP(S) response to the developer defined REST API call. Likewise, if the route is
protected
, thenuxt-saasmvp-oauth
server functionsmvpIsRestAuth
is then used in the developer's REST API Endpoint to determine if the Endpoint should be run and will return an HTTP status of401 Unauthorized
back to the client if theJWT Access Token
is invalid, otherwise the developer's REST API Endpoint will return a developer defined HTTP(S) response to the REST API call.
Security Considerations
Fundamental security considerations including integrity, availability and confidentiality of information resources were thoroughly evaluated in the design of the nuxt-saasmvp-oauth
module resulting in an implementation that is secure, lightweight and easy to use.
Protecting Secrets
The secrets used to configure the nuxt-saasmvp-oauth
module are kept in the smvp.oauth.json
file located within the application's /server
directory and are never exposed to the client.
Access Token
Access token credentials must be kept confidential in transit and storage, and only shared among the authorization server and the browser using TLS as defined by RFC 2818 to prevent interception by unauthorized parties. The authorization server ensures that access tokens cannot be generated, modified, or guessed to produce valid tokens because the symmetric key used to generate the JWT access token is only stored in the authorization server itself upon initialization of the nuxt-saasmvp-oauth
module. The Nuxt 3 application can change the symmetric key at any time by re-initializing the module with a new key.
Cross-Site Request Forgery (CSRF)
Cross-site request forgery attacks attempt to perform requests against sites where the user is logged in by tricking the user’s browser into sending a request from a different site. If the target site does not implement any CSRF mitigation techniques, the request will be handled as a valid request on behalf of the user. Since the JWT utilized in the nuxt-saasmvp-oauth
module is not stored as a browser cookie, CSRF attacks are not possible.
Cross-Site Scripting (XSS)
Cross-site scripting (XSS) attacks attempt to inject JavaScript in trusted sites. Injected JavaScript can then steal tokens from local storage. The JWT generated by the nuxt-saasmvp-oauth
module will most likely be stored in a Nuxt composable or a state management module like Pinia by the application developer. If an access token is leaked before it expires, a malicious user could use it to access protected resources. The developer using the nuxt-saasmvp-oauth
module can set the number of seconds before a token expires to mitigate the risks of XSS. The default expiration time is one hour (3600 seconds).
Replay Attacks
The nuxt-saasmvp-oauth
module uses a time-based Unix epoch nonce in the OAuth Implicit Authorization Grant for both User and REST API Endpoint authentication. This nonce guarantees the generation of the JWT Access Token within a user defined boundryTime
(default is 100 milliseconds) of the request by the client application to the OAuth Authorization Server. This mechanism is used to ensure the Authorization Grant is for a single request and exchanged for an access token thereby preventing replay attacks.
Cross Origin Resource Sharing (CORS)
The nuxt-saasmvp-oauth
module provides server middleware to handle Cross-Origin Resource Sharing. CORS is a security standard that enables servers to indicate the origins from which browsers are allowed to request resources. It was created to refine the same-origin policy (SOP), which browsers use to prevent malicious applications from accessing sensitive data on domains they do not control.