laravel sanctum, identify user from cookie - laravel

I'm new to larravel, and use laravel sanctum build an app, the session driver is cookie.
The laravel app is deployed behind caddy, I enabled caddy logs. The log format is json, I see that it contains each request headers, and cookie info is loged, so I wonder if I can identify user by the cookies, I try decode the cookie but failed, is there any method to identify user by the cookie?
this is log format
{
"level": "info",
"ts": 1648864255.073147,
"logger": "http.log.access.log5",
"msg": "handled request",
"request": {
...
"headers": {
"Accept": [
"application/json, text/plain, */*"
],
"X-Xsrf-Token": [
".....yJpdiI6Ijh6bjVZMXUvOFlkR3V1U....."
],
"Cookie": [
"XSRF-TOKEN=...eyJpdiI6Ijh6bjVZMXUvOFlkR3V1UE....9"
]
}
},
"resp_headers": {
"Set-Cookie": [
"XSRF-TOKEN=hbHVlIjoiOHN6L1BXa2N; expires=Sat, 02-Apr-2022 03:50:55 GMT; Max-Age=7200; ...",
"card_session=2IzTC9BbTEydW5NUDEvd016aVhlOWp; expires=Sat, 02-Apr-2022 03:50:55 GMT; Max-Age=7200; ...",
"hkx3q7J7TeLVf3hV9XSaDiwScSS7rUIPP7kcge7f=eyJpdiI6RzlOeEN5eUhxUVE4OUZpMkFmSmYSIsInRhZyI6IiJ9; expires=Sat, 02-Apr-2022 03:50:55 GMT; Max-Age=7200; ..."
],
..
}
}
``

I really wonder why you need to know the user from cookie.
But because you are new to laravel, I think you get it all wrong with using laravel sanctum as authenticator.
When using laravel sanctum, it will generate token to use as bearer token for your next API request. So here what you should do
login and get the user data and token
store the token in the front end and use it as bearer token for your next request.
logout and destroy the token.
The user data can be get easily in any place in the laravel backend using
Auth::user()
or maybe if you only need the user id then use
Auth:id()
don't forget to restrict your end point with authentication middleware if you don't want unauthenticated user to use your end point

My working set up
laravel app is on: http://localhost:8100
Vue app is on: http://localhost:5173
My env:
SANCTUM_STATEFUL_DOMAINS=localhost:5173
SESSION_DRIVER=cookie
SESSION_LIFETIME=120
SESSION_DOMAIN=.localhost

Related

AWS API Gateway not passing Endpoint request header even after transformation

I'm trying to pass an Authorization header through API Gateway into a Lambda function. I can see the key in the gateway logs. But, even after I transform the input with the standard script (see below), the Authorization head still doesn't make it to the Lambda function.
Any suggestions on what I'm missing?
API Log excerpt
Endpoint request headers:
{
X-Amz-Date=20220419T143450Z,
x-amzn-apigateway-api-id=?????????,
Accept=application/x-www-form-urlencoded,
User-Agent=AmazonAPIGateway_hhompg4,
Host=lambda.us-east-1.amazonaws.com,
X-Amz-Content-Sha256=??????????????????????????????????????????????????,
X-Amzn-Trace-Id=Root=1-????????-???????????????????,
x-amzn-lambda-integration-tag=abcd-4e32-1234-???????????????, Authorization=*********************************************************************************************************************************************************************************************************************************************************************************************************************************************70cc,
X-Amz-Source-Arn=arn:aws:execute-api:us-east-1:-----------------:asfd/test/POST/,
X-Amz-Security-Token=---------------------------------------// [TRUNCATED]
Method Execution / - POST - Integration Request Transformation script:
{
"method": "$context.httpMethod",
"body" : $input.json('$'),
"headers": {
#foreach($param in $input.params().header.keySet())
"$param": "$util.escapeJavaScript($input.params().header.get($param))"
#if($foreach.hasNext),#end
#end
}
}
event keys arriving to lambda function:
2022-04-19T14:29:34.457Z INFO Object.keys(event) [
'resource',
'path',
'httpMethod',
'headers',
'multiValueHeaders',
'queryStringParameters',
'multiValueQueryStringParameters',
'pathParameters',
'stageVariables',
'requestContext',
'body',
'isBase64Encoded'
]
Object.keys(event.headers)
[
'accept',
'accept-encoding',
'accept-language',
'cache-control',
'content-type',
'Host',
'origin',
'referer',
'sec-ch-ua',
'sec-ch-ua-mobile',
'sec-ch-ua-platform',
'sec-fetch-dest',
'sec-fetch-mode',
'sec-fetch-site',
'sec-fetch-user',
'upgrade-insecure-requests',
'User-Agent',
'X-Amzn-Trace-Id',
'X-Forwarded-For',
'X-Forwarded-Port',
'X-Forwarded-Proto'
]
I was able to see my request header (Authorization) in request headers but the same was not visible in the endpoint request headers. Found that you have to enable the 'Use HTTP Proxy integration' option while setting up the integration point.

Use Laravel Socialite user returns missing authorization_code

I'm using Laravel Socialite to login with SuperOffice API. Have only just added the provider as a pr but testing it already. I'm using the provider superoffice locally and inside a package superoffice-api I'm creating. Have added both packages to composer.json in the Laravel app:
"repositories": [
{
"type": "path",
"url": "./packages/superoffice-api"
},
{
"type": "path",
"url": "./packages/superoffice"
}
]
Also added the superoffice Socialite provider in the superoffice-api composer.json in the same way.
The login process is working but the problem starts when trying to use the user for other API calls. What I mean with this is on the callback I can do the following:
public function superofficeCallback(Request $request): RedirectResponse
{
$user = Socialite::driver('superoffice')->stateless()->user();
return redirect()->route('dashboard.index')->with([
'message' => 'Loggedin with SuperOffice as '.$user->name,
'success' => true,
]);
}
This shows the $user->name as expected. Now when trying to call Socialite::driver('superoffice')->stateless()->user() in the superoffice-api package I get the following error message:
GuzzleHttp\Exception\ClientException: Client error: POST https://sod.superoffice.com/login/common/oauth/tokens resulted in a 400 Bad Request response:
{ "error": "invalid_request", "error_description": "missing authorization_code"}
It doesn't matter if called in a method or in the __construct() of a class.
So my question is how can I use a Socialite provider superoffice user in a package superoffice-api? This is needed to get the access_token. Can imagine that because Socialite is called in a package some sort of reference is missing.
The problem here is that the access_token and refresh_token need to be stored in some other way in the callback function. When stored for example in the database you're able to use the tokens anywhere.

Google TaskQueue JSON API - Can not oauth - 403 Forbidden

I am attempting to use the Google JSON API - taskqueue/v1beta2
https://developers.google.com/apis-explorer/#p/taskqueue/v1beta2/taskqueue.tasks.list
I am not able to successfully authenticate for this service using the API explorer. I can use other JSON APIs like the storage API under the same project & account. When I go the the APIs tab in the developer console there is nothing listed for "TaskQueue" or "TaskQueue JSON API".
Edit: The oauth flow seems to work correctly, with scopes:
https://www.googleapis.com/auth/taskqueue
https://www.googleapis.com/auth/taskqueue.consumer
No matter what I do I get a 403 Forbidden response. How can I authorize my account to use the TaskQueue API? Here is my response from the API explorer:
403 Forbidden
cache-control: private, max-age=0
content-encoding: gzip
content-length: 146
content-type: application/json; charset=UTF-8
date: Mon, 19 Jan 2015 17:20:50 GMT
expires: Mon, 19 Jan 2015 17:20:50 GMT
server: GSE
vary: Origin, X-Origin
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "you are not allowed to make this api call"
}
],
"code": 403,
"message": "you are not allowed to make this api call"
}
}
The REST API only works for pull queues, and you need to also specify the email address of the user you are authorizing as in your queue.yaml. From the docs:
queue:
- name: pull-queue
mode: pull
acl:
- user_email: bar#foo.com # can list, get, lease, delete, and update tasks
- writer_email: user#gmail.com # can insert tasks
- writer_email: bar#foo.com # can insert tasks, in addition to rights granted by being a user_email above
Defining pull queues
https://cloud.google.com/appengine/docs/python/config/queue#Python_Defining_pull_queues

Filtering with Quickbooks Online V2 returns 401 ErrorCode=003200, Empty body posts work perfectly

We're attempting to integrate with the QuickBooks Online V2 api using Ruby 1.9.3 (not RoR).
Using the API Explorer and the Employee endpoint documentation we were able to get a simple list of test employees by using the Google Signet OAuth Gem.
require 'signet'
require 'signet/oauth_1/client'
#intialize oauth1 client
#client = Signet::OAuth1::Client.new(
:temporary_credential_uri => "https://oauth.intuit.com/oauth/v1/get_request_token",
:authorization_uri => "https://appcenter.intuit.com/Connect/Begin",
:token_credential_uri => "https://oauth.intuit.com/oauth/v1/get_access_token",
:client_credential_key => 'qyprdPEfJqU7eOze0Fby9iYhrUS5DQ',
:client_credential_secret => 'fuXsasJo4TrTEd3Yhv4TeMUizmtguh0JioIB5r2I',
:callback => "http://localhost:3000/callback/general"
)
#client.token_credential_key = 'qyprdJUtDSk7owxVfZlq7JeWO1mtpHBkSMD5GhB02PwIC6N0'
#client.token_credential_secret = 'Rq2ekgQWWL9frZAKpcgWef291mR0J5HBE354u5F3'
#setup request
original_request = [
'POST',
'https://qbo.sbfinance.intuit.com/resource/employees/v2/791630875',
# we also tried this url 'https://qbo.intuit.com/qbo28/resource/employees/v2/791630875',
[
['Content-Type', 'application/x-www-form-urlencoded'],
],
[]
]
#execute request
response = #client.fetch_protected_resource(:request => original_request)
puts response.body
As you can see the request is pretty straight-forward.
However once we create a request with a Filter in the body, we get an HTML page with the following error: HTTP Status 401 - message=Exception authenticating OAuth; errorCode=003200; statusCode=401
#setup request
original_request = [
'POST',
'https://qbo.intuit.com/qbo28/resource/employees/v2/791630875',
#'https://qbo.sbfinance.intuit.com/resource/employees/v2/791630875',
[
['Content-Type', 'application/x-www-form-urlencoded'],
],
["Filter=Name :EQUALS: Doe"]
]
We're using the Google OAuth gem, and I've verified the signature generation to be correct using these tools: LinkedIn Oauth Test Console and Beginners guide to OAuth signing requests. They both verify that the signature that Signet is generating is correct for the body I provide.
I've looked at a few SO Questions:
QuickBooks Online querying with filter returns 401 everytime
Unable to create(POST) objects (Account, customer...) on QB Windows using IDS and Sync Manager
But nothing has worked. Any help would be appreciated, we're willing to use a third party gem such as quickeebooks but we would rather not. I assume I'm just missing something simple here.
Please provide me with the following items so I can verify a working answer:
Your request parameters, including uri, header, body and exact client and access tokens (developer app tokens only please, I'll need to verify that I can generate the exact same request, including signature)
You basestring used for generating the HMAC-SHA1 signature. it will look something like
POST&https%3A%2F%2Fqbo.intuit.com%2Fqbo28%2Fresource%2Femployees%2Fv2%2F7916308‌​75&Filter%3DName%2520%253AEQUALS%253A%2520David%2520Test%26oauth_consumer_key%3Dq‌​yprdPEfJqU7eOze0Fby9iYhrUS5DQ%26oauth_nonce%3D-1787433535548338293%26oauth_signat‌​ure_method%3DHMAC-SHA1%26oauth_timestamp%3D1380089100%26oauth_token%3DqyprdJUtDSk‌​7owxVfZlq7JeWO1mtpHBkSMD5GhB02PwIC6N0%26oauth_version%3D1.0
Your response, including header and body data
I had tried to use filter query with employee endpoint. It works fine.
EDIT - Sharing endpoint, filter and resultset related to Employee API Endpoint
https://qbo.intuit.com/qbo28/resource/employees/v2/791926875
Filter= Name :EQUALS: Manas Mukherjee
header - "Authorization: OAuth oauth_token="2eRrd7LhEtHrM1CrqWvy1kmSgeukEgFxW99E1xwhSsLCp1JB", oauth_consumer_key="qyprdXsaKh0a132eNs7NTJLufjfrzm", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1380084612", oauth_nonce="1556081845430558974", oauth_signature="IMjh%2FTx%2F7GMFDE6WQqZK8b6apjI%3D"[\r][\n]"
Content-Type: application/x-www-form-urlencoded
Data Set
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<qbo:SearchResults xmlns="http://www.intuit.com/sb/cdm/v2" xmlns:qbp="http://www.intuit.com/sb/cdm/qbopayroll/v1" xmlns:qbo="http://www.intuit.com/sb/cdm/qbo">
<qbo:CdmCollections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Employees">
<Employee>
<Id idDomain="QBO">20</Id>
<SyncToken>0</SyncToken>
<MetaData>
<CreateTime>2013-09-24T21:37:22-07:00</CreateTime>
<LastUpdatedTime>2013-09-24T21:37:22-07:00</LastUpdatedTime>
</MetaData>
<Name>Manas Mukherjee</Name>
<Address>
<Line1>ABC Str</Line1>
<City>London</City>
<PostalCode>4353543</PostalCode>
<GeoCode>LAT=51.5148382,LNG=-0.1264144</GeoCode>
</Address>
<GivenName>Manas</GivenName>
<MiddleName>Kr</MiddleName>
<FamilyName>Mukherjee</FamilyName>
<ShowAs>Manas Kr Mukherjee</ShowAs>
<BillableTime>false</BillableTime>
</Employee>
</qbo:CdmCollections>
<qbo:Count>1</qbo:Count>
<qbo:CurrentPage>1</qbo:CurrentPage>
</qbo:SearchResults>
OAuth header using your tokens
"Authorization: OAuth oauth_token="qyprdJUtDSk7owxVfZlq7JeWO1mtpHBkSMD5GhB02PwIC6N0", oauth_consumer_key="qyprdPEfJqU7eOze0Fby9iYhrUS5DQ", oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1380089100", oauth_nonce="-1787433535548338293", oauth_signature="Vj67xMVhSKGjVSmGyOxt7SVv0i8%3D"[\r][\n]"
Endpoint - https://qbo.intuit.com/qbo28/resource/employees/v2/791630875
Post data to end point: Filter= Name :EQUALS: David Test
Content-Type: application/x-www-form-urlencoded
It works fine
Thanks
See this sample fiddler request with Filter for items in QBO. I cannot paste the fiddler log here. You can do it for similarly for Employee. The filters should go into the body and encode your header:
Request-
POST https://qbo.intuit.com/qbo1/resource/items/v2/723488155
HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: OAuth oauth_token="lvprdgF9q4mSQx5A6lKNm3NISXvwIpF16z",oauth_nonce="3740352e-20a4-4d45-af4f-2b783ee20e60",oauth_consumer_key="qyprd7I5WvVnPoiBh1ejZn",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1377106651",oauth_version="1.0",oauth_signature="1OAJXk5uH0sEpYpdhh%2BDMzjQFEs%3D"
Host: qbo.intuit.com
Content-Length: 28
Expect: 100-continue
PageNum=1&ResultsPerPage=100
Response Header-
HTTP/1.1 200 OK
Date: Wed, 21 Aug 2013 17:37:31 GMT
Server: Apache
Set-Cookie: qboeuid=10.129.32.5.1377106651774076; path=/; expires=Thu, 21-Aug-14 17:37:31 GMT; domain=.intuit.com
Set-Cookie: JSESSIONID=82DE11473B5246497B9FDCD8A6DA4C45.c1-pprdqboas30j; Path=/; Secure; HttpOnly
Vary: Accept-Encoding
Content-Type: application/xml;charset=UTF-8
Content-Length: 32525

Access Google Directory API from a Marketplace App using 2lo

I've spent the past couple of days trying to access Google's Directory API in Ruby but haven't been able to get it working. According to this document the Directory API can be authorized using 2lo:
If your application has certain unusual authorization requirements, such as logging in at the same time as requesting data access (hybrid) or domain-wide delegation of authority (2LO), then you cannot currently use OAuth 2.0 tokens. In such cases, you must instead use OAuth 1.0 tokens and an API key. You can find your application's API key in the Google APIs Console, in the Simple API Access section of the API Access pane.
I currently have working code that can access the Provisioning API using 2lo. From the documentation it sounds that I can use this same code to access the Directory API by just adding an API access key parameter to the request and enabling a few permissions. However, it's not working and I have no idea why.
Here is the request code:
def self.get_user2(email)
#client = Google::APIClient.new(:authorization => :two_legged_oauth_1)
#client.authorization.client_credential_key = GOOGLE_APP_KEY
#client.authorization.client_credential_secret = GOOGLE_APP_SECRET
#directory = #client.discovered_api('admin', 'directory_v1')
result = #client.execute(
#directory.users.get,
'userKey' => email,
:key => GOOGLE_API_KEY
)
JSON.parse(result.body)
end
This gets me the response:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
}
I've added the required scope to my manifest file,
<Scope id="usersAPI">
<Url>https://www.googleapis.com/auth/admin.directory.user.readonly</Url>
<Reason>See all users in your company.</Reason>
</Scope>
and also enabled the Admin SDK for my project in the API console.
Here is the log output after adding Faraday.default_connection.response :logger to my development.rb file:
get https://www.googleapis.com/admin/directory/v1/users/brian#crushing.mygbiz.com?key=AIzaSyAHYBWlC_qiihRtTKTZleZlAw2ts8Q1WO8
User-Agent: "google-api-ruby-client/0.6.4 Mac OS X/10.8.4"
Authorization: "OAuth oauth_consumer_key=\"76548528623.apps.googleusercontent.com\", oauth_signature_method=\"HMAC-SHA1\", oauth_timestamp=\"1375899810\", oauth_nonce=\"de4d976eed6883a06b3f6084e3dd0db4\", oauth_version=\"1.0\", oauth_signature=\"3D7aqhBeaCYOYyaF8bWpaM9MA8U%3D\""
Cache-Control: "no-store"
Content-Type: "application/x-www-form-urlencoded"
401
www-authenticate: "AuthSub realm=\"https://www.google.com/accounts/AuthSubRequest\""
content-type: "application/json; charset=UTF-8"
date: "Wed, 07 Aug 2013 18:23:30 GMT"
expires: "Wed, 07 Aug 2013 18:23:30 GMT"
cache-control: "private, max-age=0"
x-content-type-options: "nosniff"
x-frame-options: "SAMEORIGIN"
x-xss-protection: "1; mode=block"
server: "GSE"
connection: "close"
After searching the internet for the past day I am out of ideas for why this isn't working. Ideas anyone?
It turns out I was missing the 'xoauth_requestor_id' field. Thanks to sqrrrl for answering my question on github

Resources