Vue component with API call in Laravel + Inertia - javascript

I can't undestand how to create a new Vue component inside my app created with Laravel and Inertia.
The problem is that I can't make a call from the component to an API (in the routes/api.php file) that is protected by an auth middleware (like auth:api).
There is a practical example:
I manage a list of customers in my app. Then I manage invoices. So, in the invoice creation form I must select one of the customers in my database. I want to make a componente (like <SelectCustomer v-model="form.customer" /> maybe) where inside itself I can make an API call that return the list of all customers to populate my select.
Obviously, that API is reserved only for the logged user, so has a middleware guard.
It's possible to make an axios call - maybe - in the component's methods? but with what informations? maybe I must obtain a bearer token?

Related

How to modularize Javascript authentication code in MFE context in a VueJS

I'm working on a large,single-page VueJS application that's been broken down into several micro front-ends, and I'm currently implementing the authentication for communication with the orchestration layer and it's stumping me. The application is organized as a container application that bootstraps and mounts several other VueJS applications underneath it using single-spa
We use Azure-AD and the MSAL library for authentication and to refresh the Bearer token before each API request, and currently the application I'm working had previously stored the AD client info itself and created the authenticationContext on initialization, something like
export class Authentiation {
authenticationContext;
refreshToken;
constructor() {
this.authenticationContext = new msal.PublicClientApplication(msalConfig)
// code to initialize the
}
async acquireToken() {
// code which refreshes the token
}
}
Now, the initial authentication code has been moved into the container application since it will authenticate the user first and only then mount the apps once the user is inside. Each application, though, needs to be able to refresh the Bearer token whenever it communicates with its OL layer. Currently, it's just running the initialization again and pulling the AuthenticationContext out of local storage using the supplied keys
The goal is to modify it so that a the authentication context from the container is passed down to whatever application is being mounted up, without the need to store the AD client and context information in the app itself
What's required is that every repository within the application would have an API object injected into it, and would use this API when making requests, and the API would contain the authentication context for being able to refresh the Bearer token on each call, and this is where I'm stumped
I had thought about creating an Authentication Singleton that the API could use when being injected into a repository, but since the authenticationContext is unknown at the time, it feels weird to set it after the fact, ie something like
let authContext = new Authentication()
// setup single-spa bootstrap code
// this function is called when the container application bootstraps this Vue application
export const bootstrap = (props) =>
vueLifecycles.bootstrap(props).then(async () => {
authContext.setContext(props.authentication)
})
Then when the API gets intialized, it would have an authContext that would invoke authContext.acquireToken() to get a Bearer token to set for each refresh. But, something feels incorrect about doing this way and I'm not 100% if it's the way to go.
To summarize, applications that were once handling authentication on their own are now being passed the authentication context as a prop during load, and I'm confused about how to implement this to properly set this context as part of the API
Another team had actually stored the acquireToken function in the a Vuex store but that, to me, does not seem appropriate since it ties this code specifically to Vue

Accessing react components directly from URL

I am trying to create an new react app. I have 3 components: app (with login functionality) , admin and client.
How can I render (redirect to) admin / client based on a value (user role) , after successfully login?
Is this any way to access the admin / client components directly from the URL? More specific, localhost:3000 takes me to App.js (witch makes sense, because it is defined like this in index.js). If I want to see directly the admin component (hijacking the login), can I use for example localhost:3000/admin ? how can I do that?
Thank you !
You can use react router and in particular route.push('/admin')
You need to define the '/admin' route and voilĂ .
To bypass the login, you may want to make a 'test-admin' route and a private 'admin' route. Here is how to make a private route if you happen to need it:
https://dev.to/karanpratapsingh/private-public-and-restricted-routes-in-react-42ff
You can use react-router, that allow to define some route based on URL.
When you have a login feature, then you would probably wants to have some protected route, that are only accessible when you are logged in.
Then I recommend you to read this article

Update state from outside of components

This is a similar question but it provided solution for the specific issue of OP
I am trying to implement authentication in my React app using JWT. After logging in, server sends access token and refresh token. Access token expires shorty within an hour while refresh token is persistant for a year. Both are stored in localStorage.
I am using axios to make requests to server. I have created a file api.js that creates an axiosInstance which sets up baseURL for requests. This file exports this axios instance and every other component/ file that wants to use axios, imports it from this file - api.js. I have also set up an axios interceptor in the same file that will modify each request before sending it. It will basically add access token in authorization header if token has not expired, otherwise it will use refresh token to get new access token.
Now I have a TokenProvider Context that basically wraps whole app and it gives you token and a method to update this given token as well as the one in localstorage (useToken).
After i get the access token from the server with the help of refresh token, i want to update it in localstorage as well as the token that TokenProvider provides. I tried importing useToken from TokenProvider in api.js but React won't allow to use hooks in functions that are not components.
React Hook "useToken" is called in function "{functionName}" that is
neither a React function component nor a custom React Hook function.
React component names must start with an uppercase letter.
How should i go about implementing this functionality to update TokenProvider's token? Should i listen for events in TokenProvider that are trigged when localStorage updates or shoudl i try to convert api.js into some type of React component?
use forwardRef , read the docs here
Create function inside the components that call for your setStateName(),
and call it from the ref of your components

Restrict access to the authentified user

I'm creating my first application using Laravel and React.
I followed a tutorial online, and I noticed that the authentification, unlike what I was used to with only Laravel, is using localStorage instead of Auth::user.
With the following line I can get the informations of the authentified user :
const user = JSON.parse(localStorage.getItem("userData"));
I can access the info of the logged user like this :
{user.id}{user.name}{user.email}
Now in my application, each profile belong to a user.
Using react and react-routes, to access a profile, the user need to provide idof the profile in the addition of the url, like this :
<Route path="/customize/:id?" component={Home} />
The current problem is that any user can view any profil. I want to limit the privilege to see/modify the profiles to ONLY those who are related to the profiles. So when the user is logged, he can only manage his own profiles, or perhaps the profiles that have the sameuser_id as his id.
I searched and I found that I have to use Middlewares I think to manage the access, but I'm not entirely sure.
You're right, you should use a middleware to verify the user is authenticated.
I don't know which way you're using to authenticate a user.
Basically if you're using laravel built in authentication you should be able to use the default auth middleware as described here: https://laravel.com/docs/8.x/authentication#protecting-routes
Otherwise you may need to create a new middleware to handle the verification, the process of making a new middleware is described here: https://laravel.com/docs/8.x/middleware
Then you can use the middleware method on the routes you'd like to protect
Route::get('/customize/{id}', function () {
// Only authenticated users may access this route...
})->middleware('auth');
Another solution I would not recommend for this use is doing a simple Auth::check() in your controller's function

Microsoft App Registeration, Authentication, and Redirect URL

Using Angular 2+ with #azure/msal-angular library.
I have an app with the domain
http://localhost:4200/userId/someOtherId
So it can be any of
http://localhost:4200/2425/2532152
http://localhost:4200/35235/152115
I have a button, Login with Microsoft. On clicking that button, I call the sign in method
import { MsalService } from '#azure/msal-angular';
/// more code
signIn() {
await this.msalService.loginPopup(environment.microsoft.scopes);
//more code
}
(See sign in method here: https://learn.microsoft.com/en-us/graph/tutorials/angular?tutorial-step=3 , I do the same thing)
Now, in the application registration portal, I have
http://localhost:4200 as my redirect URI.
As a result, when I attempt to authenticate, I get the following error:
The reply url specified in the request does not match the reply urls
configured for the application
My question is, how do I solve this problem? Someone said I should be passing in state &state=userId:someotherId, but how do I do that with microsoft's authentication library for angular?
The UserAgentApplication accepts state as a property of the options object in the constructor.
However, when they created MSAL-Service which derives from UserAgentApplication it looks like they didn't expose the state parameter. I would recommend opening an issue on the GitHub repo.

Categories

Resources