Laravel How to get access token on Youtube API - laravel

I'm getting Token required error while already Enabled route option but still, it's not working.
by using this library : https://github.com/JoeDawson/youtube
could you help me to solve this problem?
Code :
class VideoController extends BaseController {
public function __construct(){
}
public function store(Request $request){
$video = Youtube::upload($request->file("video")->getPathName(), [
'title' => 'My Video',
'description' => 'This video is uploaded through API.',
'tags' => ['api', 'youtube'],
]);
return $this->sendResponse($video);
}
}

According to the documentation of that package you need to do these steps, because you may have problem with refresh_token (I guess you don't have any token in your database which must be created after logging in google)
It's important that before you begin uploading a video, you have confirmed that you have a refresh_token in your database if not these steps have to be helpful.
1- Delete all of your tokens in the youtube_access_tokens table.
2- Enable routes in youtube.php
3- Re-authenticate with Google
4- Check your youtube_access_tokens table and find the most recent token.
5- Review the token and ensure a refresh_token exists.
6- Disable authentication routes in config/youtube.php
briefly, for creating a token You need to visit your Google console and add your URL as the callback (localhost).
Then in your app, visit http://localhost:8000/youtube/auth - you will be redirected to Google and will be asked to log in. This is when you get a token and then you may not see that error again!

Related

How to use SignedRoute on example of unique register URL

I created unique url registration, when someone uses link, he will be able to register to my app.
The only problem is, my signed route is invalid and gives 0 on hasValudSignature, where might be the problem?
My register function in RegisterController:
public function register(Request $request) {
abort_unless($request->hasValidSignature(), 403, 'That link has expired or is no longer valid!');
//they can register now
}
My URL generator:
$url = URL::temporarySignedRoute(
'register',
now()->addDays(7)
);
After using my user index view it is displayed on page so I can copy link for new user. However when I try to register using this link, at the end I've got information about wrong Validation (error I made by myself to prevent from registering unauthorized people)
Is my $url written wrongly?
Edit
For some reason after typing in console php artisan route:list
I've got error that
ReflectionException::("Class "UserController" does not exist")
How might this be possible?
Edit
After remakeing controller, I'm back to the original problem with hasValidSignature

Laravel socialite

I have used laravel auth and socialite package in my web app. I have followed https://www.youtube.com/watch?v=uavoKwhGBKI&t=932s link and it working fine.To be brief, If I register using socialite it fetches the name of the user and email but needs to be filled other details as DOB and password but if I submit without filling that it shows 500 error while if I register without socialite then my validation works fine.The registration page is same.
Socialite only gives you access to a select set of data returned from a successful connection.
# Retrieving User Details
https://laravel.com/docs/6.x/socialite#retrieving-user-details
$user = Socialite::driver('github')->user();
// OAuth Two Providers
$token = $user->token;
$refreshToken = $user->refreshToken; // not always provided
$expiresIn = $user->expiresIn;
// OAuth One Providers
$token = $user->token;
$tokenSecret = $user->tokenSecret;
// All Providers
$user->getId();
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();
# Modifying LoginController
https://scqq.blogspot.com/2017/11/laravel-55-socialite-login-with-twitter.html
This guide you followed does not actually register a user by social platform. It only pre-populates the default Laravel registration form with the fields name and email as shown below. This is where you can add another property from above, such as the user's avatar, if desired. You would also need to add the corresponding field to the registration form.
return view('auth.register', [
'name' => $userSocial->getName(),
'email' => $userSocial->getEmail(),
// ... 'avatar' => $userSocial->getAvatar(),
]);
Google is NEVER going to give you someone's password!
The whole point of Socialite is to allow Google (or the selected provider) to authenticate the user — not your application.
If you wish to actually register a user with Socialite (without any additional forms or setting a password), you will need to modify or extend RegisterController.php to be able to support this.

Is this a proper Laravel Passport use case?

So think of my application as a CMS (laravel 5.7). I'm slowly adding in more javascript to make it more reactive. So I had the usual validation logic that makes sure the user is logged in and all that. But now when I use Vue to submit a comment payload it looks a little like this:
So looking at this, anyone could just change/mock the this.user.id to any number, I would like to also send a login token with the payload which then gets validated in the backend once the server receives the post request.
In the backend, ideally I'd want to have some kind of safe guard that it checks whether the api_token of the user matches with this.user.id to ensure the user.id wasn't mocked on the front end.
I read this portion: https://laravel.com/docs/5.7/passport#consuming-your-api-with-javascript
Part of it says:
This Passport middleware will attach a laravel_token cookie to your outgoing responses. This cookie contains an encrypted JWT that Passport will use to authenticate API requests from your JavaScript application. Now, you may make requests to your application's API without explicitly passing an access token:
But I'm still a bit unsure how that JWT gets generated in the first place. I don't have the vue components for the create token crud added because I want it to be done automatically. I think I'm slightly overthinking this..
Is this a good use case for Laravel Passport? I was looking through the tutorial and right now I don't have a need for custom oauth token creations and all the crud. I just want a unique token to be saved on the user side, that can expire, but also be used to validate requests. Am I on the right track here with Passport or should I use a different approach?
postComment(){
axios.post('/api/view/' + this.query.id+'/comment',{
id: this.user.id,
body: this.commentBox
})
.then((response) =>{
//Unshift places data to top of array, shifts everything else down.
this.comments.unshift(response.data);
this.commentBox = '';
document.getElementById("commentBox").value = "";
flash
('Comment posted successfully');
})
.catch((error) => {
console.log(error);
})
},
Update - Reply to Jeff
Hi! Thanks for your answer. It's not an SPA (might be in the future), but the comment box and the comment section is also integrated with websockets and there's a laravel Echo instance on it.
I guess where I'm feeling uncertain is the security of it.
I pass a user prop with :user="{{Auth::check() ? Auth::user()->toJson() : 'null'}}" into the vue component that contains the postComment() function.
This is where the id: this.user.id comes from. The route is defined in the api.php in a route middleware group for ['api'] like so:
Route::group(['middleware' => ['api']], function(){
Route::post('/view/{query}/comment','CommentController#store');
});
In my controller which calls a service to create the comment, the $request
public function makejson(createNewCommentRequest $request, Query $query){
$comment = $query->comments()->create([
'body' => $request->get('body'),
])->user()->associate(User::find($request->id));
$id = $comment->id;
$comment->save();
}
The createNewCommentRequest is a FormRequest class.
For now the authorize() function just checks whether the request()->id is an int:
public function authorize()
{
if(is_int(request()->id)){
return true;
}
return false;
}
From within there if I log the request(), all it outputs is:
array ( 'id' => 1, 'body' => 'gg', )
I thought I would need to add logic to authorize the request based on whether the user token and the request() yield the same user id? I'd want to avoid the scenario where someone can modify the post request and comment using another users id.
In the Network section of devtools, in the Request headers, i see it pushed a laravel_token cookie. I'm assuming that laravel_token is what stores the user session? If so, how would one validate based on that token?
I was playing around and added the route:
Route::get('/token', function() {
return Auth::user()->createToken('test');
});
When I went to it i got the following:
{
"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImE4NDE2NGVkM2NkODc5NDY3MzAxYzUyNmVkN2MyMGViZTllNzJlMGMzMjRiMmExNWYzZDgwZGNmMzEzMDk1MTRmNTY1NGMxYWUwMTE2ZGRkIn0.eyJhdWQiOiIxIiwianRpIjoiYTg0MTY0ZWQzY2Q4Nzk0NjczMDFjNTI2ZWQ3YzIwZWJlOWU3MmUwYzMyNGIyYTE1ZjNkODBkY2YzMTMwOTUxNGY1NjU0YzFhZTAxMTZkZGQiLCJpYXQiOjE1NDY1NTQzNDEsIm5iZiI6MTU0NjU1NDM0MSwiZXhwIjoxNTc4MDkwMzQwLCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.NMETCBkOrMQGUsXlcas6CvTFJ0xRC8v4AJzC5GtWANdl8YsPBGlyCozMe1OGc8Fnq8GC_GZFkKmMT27umeVcSyaWriZB139kvtWzY6ylZ300vfa5iI-4XC_tJKoyuwDEofqMLDA4nyrtMrp_9YGqPcg6ddR61BLqdvfr0y3Nm5WWkyMqBzjKV-HFyuR0PyPQbnLtQGCzRFUQWbV4XWvH2rDgeI71S6EwmjP7J1aDA2UBVprGqNXdTbxWpSINMkZcgrDvl4hdqNzet-OwB2lu2453R-xKiJkl8ezwEqkURwMj70G-t9NjQGIBInoZ-d3gM2C3J9mEWMB5lyfSMaKzhrsnObgEHcotORw6jWNsDgRUxIipJrSJJ0OLx29LHBjkZWIWIrtsMClCGtLXURBzkP-Oc-O9Xa38m8m6O9z-P8i6craikAIckv9YutmYHIXCAFQN2cAe2mmKp7ds1--HWN_P5qqw6ytuR268_MbexxGDTyq8KzUYRBjtkgVyhuVsS7lDgUHgXvJfHNmdCulpiPhmbtviPfWaZM19likSjKHLTpIn2PpfTflddfhB9Eb4X24wGH7Y5hwxASe7gDs_R707LphS1EH4cTE8p2XW_lLv0jo89ep9IUPUO27pWLsqabt8uTr5OoKQeNZmXT6XiJ9tK3HhRgvIt7DYt8vqlRw",
"token": {
"id": "a84164ed3cd879467301c526ed7c20ebe9e72e0c324b2a15f3d80dcf31309514f5654c1ae0116ddd",
"user_id": 1,
"client_id": 1,
"name": "lol",
"scopes": [],
"revoked": false,
"created_at": "2019-01-03 22:25:40",
"updated_at": "2019-01-03 22:25:40",
"expires_at": "2020-01-03 22:25:40"
}
}
Now in Postman, when I send a get request to:
Route::middleware('auth:api')->get('/user', function (Request $request){return $request->user();});
I added a authorization header of type Bearer Token for the string captured in the variable: accessToken. In return I get the user, no issue. However where and how is the accessToken generated? It's not saved in the database?
Take the user ID that Laravel gives you from the token, rather than sending it from the front end. You can also check the scopes assigned to the token:
Route::post('/api/view/{query}/comment', function (Request $request, Query $query) {
if ($request->user()->tokenCan('comment-on-queries')) {
$query->comments()->create([
'body' => $request->get('body'),
'user_id' => $request->user()->id,
]);
}
});
If this isn't a single page app, and only the comment box is handled by ajax, the default Laravel scaffolding should handle this by adding a CSRF token to axios config. In that case you don't need Passport, because the user is stored in the session. Still though, don't take the user ID from the front end, get it from \Auth::id()
Here's the key difference: If they login using PHP, your server has a session stored and knows who is logged in.
If you are creating a single-page app separate from your Laravel app, you have to rely on Passport and tokens to ensure the user has the authority to do what they're trying to do.
Figured it out, was overthinking it. Basically didn't need a whole lot to get it working.
Added the CreateFreshApiToken middleware to the web group in app\Http\Kernel.php.
The axios responses attach that cookie on the outgoing responses
The api middleware group had to be 'auth:api'.
The user instance can be then called via request()->user() which is awesome.

Token Passport Users

I'm new to building APIs, and I'm using Laravel and some packages, like Passport.
In this project I'm creating an API to communicate with a mobile app and make some tasks, like creating users and adding some information related to the users.
I'm already getting the idea of how it works with tokens, and I already have almost everything done. My only question is, for example, before I create a register user to receive the token I have other information being presented in the mobile app, like news, and some listing information that is not needed to login or register.
In my API I already have these routes ready, but I cant access this information because I need a token.
How do iI handle this situation? When I need to access information, where I cant present it?
Use your controllers to retrieve the data you need from your database and then return a response with the data and create a token for the user:
...
$status = 200;
$response = [
'data' => Your data (user info, listings, news...),
'token' => Auth::user()->createToken("YourTokenName")->accessToken,
];
return response()->json($response, $status);
Then you could store that token in localStorage:
axios.post('your-api-route')
.then((response) => {
localStorage.setItem(`${"YourTokenName"}.jwt`, response.token);
...
})
And finally attach that token to the api routes that require authentication:
axios.defaults.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem(`${YourTokenName}.jwt`);

Problem getting codeigniter library for google reader to work when trying to log in and get feed data

I'm trying to getting this http://www.forgottenexpanse.com/projects/ci_reader CodeIgniter library for interacting with Google Reader to work.
When following the examples on the page, this works fine:
$this->load->library('reader');
$shared_items = $this->reader->shared_items('12006118737470781753');
foreach ($shared_items['items'] as $entry) {
echo $entry['title'];
}
But when trying to grab non-public data by loging in:
$this->load->library('reader');
$credentials = array('email' => 'me#gmail.com', 'password' => 'mypassword');
$this->reader->initialize($credentials);
$shared_items = $this->reader->shared_items();
foreach ($shared_items['items'] as $entry) {
echo $entry['title'];
}
I get a bunch of warnings related to line 454 of libraries/Reader.php, like this one:
Message: simplexml_load_string(): Entity: line 128: parser error : StartTag: invalid element name
I'm hoping someone has an idea what might be happening here.
Thanks much!
The library you point to still uses the SID cookie to authenticate with Reader. That was deprecated a few months ago. The new preferred authentication schemes are either OAuth or ClientLogin with an authentication token; both are described at http://code.google.com/p/google-reader-api/wiki/Authentication.
In this particular case, you'll have to modify the _login function to get the Auth token out of the ClientLogin response. Once you have it, you'll also need to modify the _fetch function to include it as the Authorization header (instead of adding the cookie).

Resources