Managing OAuth2 redirections on the frontend: Best practices

I am currently working on implementing an OAuth2 flow for a Single Page Webapp, but I am facing challenges in dealing with Frontend/JavaScript redirects.

Regarding the backend setup, I have it all sorted out: utilizing a library that takes care of everything and provides 2 routes:

  • /auth/authorize returns a JSON response as follows:

    { "authorization_url": "https://github.com/login/oauth/authorize?response_type=code&client_id=d263f54&redirect_uri=http%3A%2F%2Fxxx&state=eyJ0eXAiOiJkdjsfkj&scope=read" }
  • /auth/callback is called back as the redirect_uri by the OAuth provider (such as Github), returning either a JSON response like:

    { "access_token":"jhfgkjhdfkjghkdhgkdhgfd","token_type":"bearer"}

    (if Bearer authentication is used), or simply null (in case of Cookie authentication. In this scenario, the cookie is appropriately set on the browser)

How should I go about handling this on the frontend side?

When a user clicks the Login button, I can easily redirect them to the OAuth provider login page using:

window.open(axios.get('/auth/authorize').data.authorization_url);

without any issues.

However, if I register the callback in my OAuth provider as /auth/callback, the user will end up on a plain text page after redirection, which is not ideal.

I believe I need to set up a Frontend route as the OAuth provider callback, where this route listens to the response from the OAuth provider and forwards the exact same response to the backend's auth/callback.

So, how can I achieve this using Axios/Javascript?

Is there a recommended/best practice approach for this situation?

Thank you!

(For additional information, the backend library I am using is FastAPI-Users and the frontend is built using Vue.js)

Answer №1

In my experience, I have found it most effective to set the redirect URI as the base path of the application and handle the OAuth response when the app is loaded. Take a look at this React code example that demonstrates this approach.

I also incorporate pre and post login logic to manage login response URLs in the browser history and restore the application state for seamless deep linking functionality.

MULTI TAB BROWSING

The use of a handlePageLoad method mentioned above can be helpful for establishing authentication state when a user opens a new tab or reloads the page. Running this method from any path instead of a specific route can offer better versatility.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using an AWS API Gateway, an HTTP client sends a request to access resources

I have a frontend application built with Angular and TypeScript where I need to make an HTTP request to an AWS API Gateway. The challenge is converting the existing JavaScript code into TypeScript and successfully sending the HTTP request. The AWS API gat ...

The art of efficiently handling and outputting an array of files using node

In a folder filled with markdown files like so: myDir |- fileA.md |- fileB.md |- fileC.md |- fileD.md I want to extract just the filenames without the file extension and store them in an array. This is my attempt: var mdFiles = fs.readdir('myDir&a ...

What could be causing a tooltip to remain visible even after a mouseleave event in a React application

My goal is to display a tooltip when the mouse enters an item, and hide it when the mouse leaves. I created a demo that works perfectly fine. Check out the working demo here The above code successfully shows the tooltip on hover and hides it on leave. I ...

An uncomplicated broadcasting and receiving method utilizing an event emitter

This code is from chapter 3, example 11 of the book Node.JS in Action, found on page 52. var events = require('events'); var net = require('net'); var channel = new events.EventEmitter(); channel.clients = {}; channel.subscriptions = ...

Is there a way for me to dynamically decide whether to use the append or prepend function?

Utilizing jQuery to retrieve data from the controller and populate a calendar represented by a table with days in columns. Implementing functionality for navigating between previous week / next week, as well as previous day / next day. The four scenarios s ...

Whenever there is a click event triggered within the map function, it will affect every element within the collection

I am struggling to make changes to a specific item in the map function when clicked. Can someone assist me with achieving this functionality? const Product = ({categories}) => { const [active,setActive] = useState(true) function activeCat ...

The parent's setState does not trigger the child's componentWillReceiveProps

Within my application, there is a parent component and a child component with props connected to the parent's state. When I call setState in the parent component, the componentWillReceiveProps function of the child component does not always get trigg ...

Transform nested entities into a single entity where any properties that are objects inherit from their parent as prototypes

Exploring a new concept. Consider an object like: T = { a: 2, b: 9, c: { a: 3, d: 6, e: { f: 12 } } } The goal is to modify it so that every value that is an object becomes the same object, with the parent object as prototy ...

Reorganizing an array of JSON data by date value with a limitation to just one

Currently, I am attempting to organize a JSON array based on the date key. However, it appears that my sorting function is either stopping after one sort or simply not functioning correctly. Here is the JavaScript code for my sorting function: function ...

Issue with Google Charts - Chart is unable to render because data table has not been defined

Using Ajax, I attempted to set an Interval for my Google Chart, but unfortunately, the Chart is not being drawn. Instead, I repeatedly receive the error message: "Data table is not defined." every 5 seconds. If you want to see a screenshot of the error mes ...

Basic calculation of movement yields inaccurate outcome

I am encountering an issue with this specific function implementation. Calculations.add(this, //CONTEXT function () { //CALUCATE this.position.x += (this.movementSpeed.x / 10); }, function () { //HAVE CALCULATED ...

Using the same conditional statement on multiple pages within a Next.js application

I'm currently working on a project with Next.js and I've encountered an issue when fetching data from my server using the useSWR hook. There are certain conditions that need to be met in order to display specific content on the page, as shown in ...

Exclude a specific tag from a div in JavaScript

I need help selecting the text within an alert in JavaScript, excluding the <a> tag... <div id="addCompaniesModal" > <div class="alertBox costumAlertBox" style="display:inline-block;"> <div class="alert alert-block alert- ...

inSession variable in express: set to false

i keep receiving inSession:false when attempting to log in, it is expected to return true. I am utilizing express session, in combination with postges and sequalize. I have logged the state values and they are being rendered correctly, so they are n ...

What is the most efficient way to extract a key and its corresponding value from an object containing only one pair?

Currently, I am developing a recipeBox application using React JS. Within this application, there is a state defined as: this.state = { recipeArray: [] ...} Users have the ability to add recipes by pushing objects {recipe_Name : Ingredients} into tha ...

The <servicename> is inaccessible within an error function in Angular2

I encountered an unusual issue in angular2. While the code below is functioning correctly: loginResult.subscribe( (data) => this.response = data, (err) => this._ajaxService.handleError(err, 'A string to summarize th ...

retrieving information from the database and passing it to the controller

I'm in the process of developing a new API with Express, following the MVC architecture. However, I've been facing difficulties getting the data to successfully return from the database access file to the controllers file. Initially, I attempted ...

"Optimize your website by incorporating lazy loading for images with IntersectionObserver for enhanced performance

How can I use the Intersection Observer to load an H2 tag only when the image is visible on the page? Here is the JavaScript code I currently have: const images = document.querySelectorAll('img[data-src]'); const observer = new IntersectionObser ...

Generate a new core element featuring the top 10 users

In my app, I have a function that sorts users in the mobile_user table based on their earned points and assigns them a rank. This function is triggered every time an http request is made. Now, what I want to achieve is creating a new root node called lead ...

Initial 16 characters of the deciphered message are nonsensical

In a specific scenario, I encounter data encryption from the API followed by decryption in TypeScript. I have utilized CryptoJS for decryption in TypeScript. Below is the decryption code snippet: decrypt(source: string, iv: string): string { var key = envi ...