I previously taught my self php, but now I want to migrate to a framework I have chosen Lavarel currently.
I have been able to do this directly in plain php, but I am having problem re-implementing it in the newest version of Lavarel.
I created a controller based on the google Calendar API.
The first step is authenticating, and that is where my problem exists.
I do the setup, display the google permissions, and accept the permissions. At this point Google does a callback.
If I route the callback to GoogleCalendar#callback then it calls the constructor again re-displaying the google authentication request in an infinite loop.
If I route the callback to another class it gets the tokens, but then the wrong class has the token. I have placed the token in a database, but how do I transfer execution back to the GoogleCalendar class.
return redirect()->action('GoogleCalendar#part2',['code' => $input['code']]);
This fails, even though the class and function exist I get an error message like they don't.
I was able to store the token in the user table, however, I need to pass control back to the GoogleCalendar controller with an operative $client string.
Related
First important information: I’m new to Laravel, so your patience is appreciated.
I’m currently migrating a framework of mine to Laravel and still in the early stages. I know that Laravel has it’s own database construction mechanism that is recommended to use the migrations and the Models, however, for my purpose, I’d like to use my own database that I use in other systems that I’ve built in the past. The idea for this system is to have a shared database, but operable through different tech stacks.
This is my current scenario:
Laravel 8
Sanctum 2.14
Frontend (Laravel):
I’ve built a very simple login page that has a controller and sends data (user and password) to my backend (Laravel). In the backend (different server), I grab the data and check if the data is correct. Being correct, I send a json response with some data, like:
returnStatus = true
loginVerification = true
IDCrypt = asdfasd4fa654sd54a (encrypted ID to grab in the frontend again)
Up till here, it’s working fine, as I wanted and very similar to my legacy systems.
My idea would be to get this response in the frontend, via auth token managed by Sanctum and use a middleware to check the token in order to let the user access some web routes.
I’ve watched some videos, but I’m only finding videos that use all the database mechanism that Laravel provides.
However, my intention would be to generate the token with data from my own table and data objects I created (without any existing Laravel´s models).
Is there a way for me to do this?
How would I set the token in the backend and include in my response?
How would I grab the token in the frontend in a secure way?
Lets say you have a model LegacyUser and this is your existing authenticable entity.
In this model simply override methods defined in the Laravel\Sanctum\HasApiTokens trait. Specifically createToken and the tokens relation for your use case by the sounds.
Then you can create tokens anywhere like usual with
$user = LegacyUser::find( $id );
$token = $user->createToken('token-name');
Then us the token as usual.
NOTE: if you're also changing how the tokens are stored/retrieved you'll need to set the token model, docs cover that here: https://laravel.com/docs/8.x/sanctum#overriding-default-models
If you want to avoid using authenticable entites (ie, no laravel models) entirely that's going to be more complicated and Passport might be a better shout, as client_credentials dont need to be associated to a user entity.
Alternatively: Write your own middleware that is compatbile with your existing auth process.
I created an API to login in my web app. After checking the parameters, use the Auth method: loginUsingId() with the id of the user to be logged in.
After that I get authenticated correctly, in fact doing an echo Auth::user() shows the user property correctly.
However, by making a redirect to another project page, I am no longer logged in the portal and shows me the login page.
It seems that the user's session does not remain or that is not created at all.
I use Laravel 5.6. I have no middleware for the route.
Each time your page accesses the API, it's essentially talking to a brand new instance of the API.
Think of it like this. Your "login" endpoint is not actually telling the API to log someone in. It's telling it to merely verify the caller's claim that the given password belongs to the given user, end of story. If you want to turn that authentication into actual "login" behavior from the UI perspective, there's other steps you need to take.
If Laravel is serving up Blade files for your site, then it's a different story. Out-of-the-box, it generates a Php session for you, and sends the session-key cookie to the browser for use in subsequent requests.
Similar to a session-key, for maintaining a session between a website and a separate API, you need each subsequent call to include a token. And you need the login endpoint to provide that token upon successful authentication.
Passport is one way to go, but it might be overkill for your situation. Passport is good for handling users, clients, and authorization permissions. But if all you want is authentication and you're not as concerned with controlling what they have access to beyond that, then I highly recommend Tymon JWT-Auth.
Both Passport and JWT-Auth use "bearer tokens" in the 'Authorization' header. There're other kinds though, like "basic tokens". A basic token is just an encoded concatenation of the username and password. Laravel supports this with a route middleware, but I do still recommend going with JWT.
One of the nice things about JWT is you can actually include extraneous data within the token itself. And it positions you better to lean into Passport (OAuth2) if/when you need it, by not requiring your client-side to change its authentication method.
Firstly I'm a real beginner with Laravel so I will try to describe my problem as best as I can.
I am building a website using Laravel however the information on users will not be stored on my server but rather externally on another server.
The only way to access the user's data is through an external API; I am not allowed access to their database. The API request returns a token and I use this token to check with their server to see if the user is logged in.
My question is: how do I authenticate the user so that I can still use Laravel's out of the box guards.
It's really handy to use methods like Auth::check() to determine if the user is still logged in.
You'll either need to modify Laravel's default authentication middleware in app/Http/middleware/Authenticate.php or you'll need to create your own middleware class that runs the authentication that you need. Create a class in the app/Http/middleware folder and register that middleware. https://laravel.com/docs/master/middleware
I'm working for this website that allows you to schedule teaching sessions with teachers online on different subjects. We recently added the option for a user to link their google calendar so that every new teaching session they schedule, it's automatically created on their calendar.
This is working great. I've got refresh tokens (offline access) for when the access token expires. So this is all working as it should.
The problem is, when both the teacher and the user have their calendar linked, and my function attempts to create the same event for both, the first one gets created (lets say, for the user), but for when it's time to create the same event for the teacher, it fails with a 404 "notFound", as if it didn't find the calendar.
My guess is that I'm using the same google client object, and you probably can't change the access tokens once you set them. I've tried unset() or $this->gclient = null but it's not working.
I'm using CodeIgniter, so I created a library for google calendar api. In my code, I do something like this:
...
if ($user->hasGoogleCalendar) {
$this->addEventToCalendar($user, $event);
}
if ($teacher->hasGoogleCalendar) {
$this->addEventToCalendar($teacher, $event);
}
...
function addEventToCalendar($user, $event) {
//the constructor for gcalendar creates the google client
$this->load->library("gcalendar");
//this verifies the access token, refreshes if necessary and
//creates the event
$this->gcalendar->addEventToCalendar($user->access_token, $user->calendarId, $event);
}
So this works the first time (for the $user), but then fails (404 notFound) for the $teacher. If I invert the first if statements (so that the teacher is first, then the user), then the teacher gets the event on his/her calendar and the student does not.
So basically the problem is that I can't set a new access_token for the same Google Client, or something like that. I've tried to unload the library and load again but haven't found a way to make it work.
I also tried:
$this->load->library("gcalendar", NULL, "gcalendar1");
$this->load->library("gcalendar", NULL, "gcalendar2");
But it's the same, now I've got 2 different objects $this->gcalendar1 and $this->gcalendar2 but the same error occurs.
For my library I'm using Google Api PHP client
Any ideas?
OK. I analyzed the Google Client class, and it creates a file based cache for the user credentials/data. So the problem was that when a user connected their google calendar account and their data was stored in a file. If another user tried to connect their google calendar, the class wouldn't get this user's credential but instead use the cache file (if it was still valid, I'm guessing time based), but this cache contains files for the first user. So basically user B had a refresh token / access token that belonged to user A, that's why it failed.
For now, I've modified the Google Client class and forced it to not use a cache. I'll do some more research on this because the cache must be there for a reason.
Now it's working like it should!
For my API, I have a database of items and users. API calls follow the format of
POST(GET, DELETE, etc.) http://example.com/api/items/4
When a user calls an API, I'd like to be able to get the id of the item to make sure that the user actually has permission to modify the item. I'm able to get the user ID without any problem (extracting it from the OAuth2 token), but what's the best way to get the item ID, in this case 4? I would prefer to do this in the __isAllowed() function in the iAuthenticate class to keep my code clean. Is this possible?
Although it is possible, it will complicate the process to reject the user based on the resource at the auth class level.
I always prefer to do this at the api method level, we can still throw 401 Unauthorized from the api method once we find the requested resource does not belong to the user