Turbolinks and Ruby Shopify_app 20.1 - ruby-on-rails

My shopify app uses shopify_app 19 and turbolinks to load the code into the embedded app:
Turbolinks.visit(data.loadPath);
Until today, I just needed to add the session value in the header:
xhr.setRequestHeader("Authorization", "Bearer " + AppBridge.sessionToken);
But after I upgraded to the new 20.1.0 version, nothing is working. Looking into the code:
https://github.com/Shopify/shopify_app/blob/main/lib/shopify_app/controller_concerns/login_protection.rb#L222
apparently now the app is expecting that I must send the "session":
params[:session].present?
and "shop" params (values) on each single request. But I don't know how to do that with Turbolinks.

Related

Get CSP nonce working with Rails javascript_packs_with_chunks_tag

I am using Rails 5.2 with webpacker 4 and recently switched to using splitChunks. My web pages now reference my web pack using the javascript_packs_with_chunks_tag.
Now that I want to start using CSP (Content Security Policy) with the SecureHeaders gem I am coming across CSP errors:
homepage-5879edcf6f8ba98035c2.chunk.js:2
[Report Only] Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'nonce-dlcwKLQTKthCJgmDqEWu1SX05nIjRY/9r+6ixP5CP4A=' 'unsafe-inline'".
I know SecureHeaders gem have a nonce helper method for normal javascript tags: nonced_javascript_include_tag.
Does anyone know how to add nonce to the javascript_packs_with_chunks_tag to eliminate this error?

Angular with Rails API: "Failed to load resource: the server responded with a status of 401 (Unauthorized)"

So I am deploying an Angular 5 app with a Rails 5 back-end. I can get the data to flow properly between the two locally, but trying to connect to the deployed version of the API (which is on Heroku) I run into some authorization issue. The error is:
Failed to load https://my_api.herokuapp.com/data.json: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:4200' is therefore not allowed access.
The response had HTTP status code 404.
Cross-Origin Read Blocking (CORB) blocked cross-origin response <URL> with MIME type application/json.
See <URL> for more details.
Is this something I need to change within the Rails API or in Angular? The deployed Rails API is essentially the same as the local version so I'm not sure where the disconnect is coming from.
There are only two refrences to the API in Angular. I connect to it the same way that I do to the local server:
Angular, app-module.ts
providers: [Angular2TokenService, AuthService, AuthGuard,
// {provide: 'api', useValue: 'http://localhost:3000/'}
{provide: 'api', useValue: 'https://my_ api.herokuapp.com/data.json'}
]
Perhaps it's my use of Angular2TokenService?
Angular, environment.ts:
export const environment = {
production: false,
token_auth_config: {
// apiBase: 'http://localhost:3000'
apiBase: 'https://my_api.herokuapp.com/data.json'
}};
Thanks! Let me know of any suggestions you might have or if you need clarification.
It's issue with CORS(cross-origin-resource-sharing). You can handle it by adding callback in your API like below:
def cors_set_access_control_headers
headers['Access-Control-Allow-Origin'] = ENV['SERVER_URL'] || '*'
end
where SERVER_URL is your front-end server URL
Else you can use gem 'rack-cors' as suggested in comments by #Kedarnag Mukanahallipatna

Rails w/ Google API Client: header field value cannot include CR/LF

ArgumentError in Users::OmniauthCallbacksController#google_oauth2
header field value cannot include CR/LF
Really unsure where this error is coming from.
I'm using ruby 2.5, Rails 5, and google-api-client 0.8.2
Any ideas how to fix or what information I can provide to make this question more informative?
Update: My logs show this when I am trying to authorize with Google's API
Google::APIClient::Request Sending API request get https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest {"User-Agent"=>"hello U/1.0.0 google-api-ruby-client/0.8.2 Mac OS X/10.13.4\n (gzip)", "Accept-Encoding"=>"gzip", "Content-Type"=>""}
And from my research, CRLF is "\r\n" characters, right?
So "User-Agent"=>"hello U/1.0.0 google-api-ruby-client/0.8.2 Mac OS X/10.13.4\n
is probably the issue.
So my question would be- how do I access User Agent in my request to fix this issue with Rails 5?
When using the Google::APIClient, the generated User-Agent may contains a CRLF. It can can be overridden in constructor. Example :
Google::APIClient.new(application_name: 'Foo', application_version: '1.0', user_agent: 'Foo/1.0 google-api-ruby-client/0.8.6 Linux/4.15.0-65-generic (gzip)')
You can modify the user_agent string to remove the CR/LF. I am using Rails 4.1.8 and google-api-client version `
#api_client = Google::APIClient.new(:application_name=>"Chronos", :application_version=>0)
# work around a bug that puts a CR/LF in the user agent string
#api_client.user_agent = #api_client.user_agent.gsub("\n", "")
Update gem google-api-client to version 0.20.0. It solves the problem but requires other changes to the application
Updating the version of the google-api-client gem did the trick for me.

rails 4 API gives 401 unathorized response after successful log in using angular2-token package

I have a setup in which I have a rails 4 API having the gem devise_token_auth and hosted as a separate application so I have also rack-cors configured to handle cross origin requests. Using angular2-token on my front end Angular 2 applicaiton I have been able to successfully sign up and sign in as well as sign out users via my API.
The issue however, which I have encountered occurs only when the user is signed in and upon refreshing the browser I get this error in the rails API console as well as in the browser, checked in firefox as well as chrome.
Started GET "/api/v1/auth/validate_token" for 127.0.0.1 at 2017-02-06 17:42:49 +0500
Processing by DeviseTokenAuth::TokenValidationsController#validate_token as JSON
followed by
SELECT "users".* FROM "users" WHERE "users"."uid" = $1 LIMIT 1 [["uid", "abc#xyz.com"]]
Completed 401 Unauthorized in 76ms (Views: 0.2ms | ActiveRecord: 0.3ms)
My initial assumption during the configuration of this package in my Angular2 app was that it will implicitly include authentication headers in each request. However after repeatedly going through the gem's documentation I also added the headers myself when I initialize the token service in my app.component.ts file.
this._tokenService.init({
apiPath: API_PATH,
globalOptions: {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
"access_token_name": localStorage.getItem('accessToken'),
"client_name": localStorage.getItem('client'),
"uid_name": localStorage.getItem('uid')
}
}
});
Even after that the response hasn't changed to the request and I was unable to receive these headers on the server end as well.
However after hours of inspection an idea finally came to me which was to inspect the headers m getting on the server and when I used ruby's request.header.inspect on my server end application I get the following output with the information required for validation of the token but it seems that the name of the keys of these header values are different form what the devise_token_auth expects to validate token (I went through the source of the devise_auth_token gem here.
"HTTP_ACCESS_TOKEN_NAME"=>"xxxxxxxxxxxxxxxxxx", "HTTP_EXPIRY"=>"xxxxxxxxxxxxxxxxxx", "HTTP_UID"=>"abc#xyz.com", "HTTP_CLIENT_NAME"=>"xxxxxxxxxxxxxxxxxx", "HTTP_TOKEN_TYPE"=>"Bearer"
What I believe is the user is not being set by the devise_token_auth gem based on the headers that are being passed.
After repeatedly going through the documentation of Angular2-token as well as devise_token_auth gem I am confused whether or not to manually add headers for authentication because I believe they are being passed already but with different keys.
I would just like to know if that is the case I am experiencing its been almost a full day and I cannot figure out a way to pin point the reason behind the 401 response.
Thanks a lot.
EDITED:
Moreover I am also getting nil when accessing current_user or any devise helper after successful sign in on server end.
Here are the rack-cors configuration for my api rails applicaiton as well.
application.rb
config.middleware.use Rack::Cors do
allow do
origins '*'
resource '/cors',
:headers => :any,
:methods => [:post],
:credentials => true,
:max_age => 0
resource '*',
:headers => :any,
:expose => ['access-token', 'expiry', 'token-type', 'uid', 'client'],
:methods => [:get, :post, :options, :delete, :put]
end
end
The headers I get upon inspecting are following:
HTTP_ACCESS_TOKEN
HTTP_CLIENT
HTTP_EXPIRY
HTTP_TOKEN_TYPE
HTTP_UID
These are the headers sent even if I don't mention any headers while configuring the angular2-token package.
I am confused why it lets me login in the first place and later throw an error with a 401 code and response of
{"success":false,"errors":["Invalid login credentials"]}
When I try and manually check token's validation using the following code
this._tokenService.validateToken().subscribe(
res => console.log(res),
error => console.log(error)
);
You should also pass Expiry and Token-type on requests for devise_token_auth to authenticate, something like this:
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Uid', this.uid);
headers.append('Client', this.client);
headers.append('Access-Token', this.access_token);
headers.append('Expiry', this.expiry);
headers.append('Token-Type', 'Bearer');
this.http.post('http://my-api.com/', JSON.stringify(resource), {headers: header}).subscribe((res)=>{
#Your Logic Here
});
This example is for generic HTTP requests, but you can apply that rule on your angular token plugin. ie.:
this._tokenService.init({
apiPath: API_PATH,
globalOptions: {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
"access_token_name": localStorage.getItem('accessToken'),
"client_name": localStorage.getItem('client'),
"uid_name": localStorage.getItem('uid'),
"expiry_name": localStorage.getItem('expiry'),
"token-type_name': 'Bearer'
}
}
});
You have set custom headers name for devise_token_auth? First example works with default configuration, without _name in the end of the headers' names, you should try modifying if that is the case.
After spending a few days on this issue and going through multiple threads of related issues repeatedly posted on related topics I came across the following issue and I realized I have rails 4 and have used rails-api gem to generate my API.
After that I created a rails 5 API with --api option (without rails-api gem) and with devise_token_auth and rack-cors on my api end I was successful in sending authorized request using the angular2-token package. Along with that I was also able to send authorized http post requests with the authorization headers access-token, token-type, expiry, uid as mentioned in the devise_token_auth gem's documentation.
This might not be the exact solution or I may not have pinpointed the cause of the issue but this was what worked for me.

404 not found with api call - Angular to RoR

I am a newbie with Ruby on Rails and I am trying to figure out ways to connect Angular to RoR in a very simple way
Here is my service
mWebApp.service('mWebSrvc', function($http, $log) {
this.getCustomers = function() {
$http({
method : 'GET',
url : 'http://127.0.0.1:3000/api/customers/'
}).success(function(data, status, headers, config) {
$log.log('Done');
angular.forEach(data, function(c) {
$log.log(c.Title);
});
customers = data;
return customers;
});
};
});
When I look under the Net tab in Firebug, I see OPTIONS /api/customers/ 404 Not Found, but if I click on the Response tab within, then I see the JSON file - WTF? And not the JSON tab - again, WTF?
Under Firebug's console -
"NetworkError: 404 Not Found - http://numberForLocalHost:3000/api/customers/"
My Rails server is running in daemon mode - numberForLocalHost:3000 - is this what the issue might be? That it should be calling a true api
If I paste the URL above into any web browser, then I can see the JSON
As usual, thanks in advance
You're getting an OPTIONS request because your browser believes this is a cross origin request.
See this question for example. Is your RoR app also serving your client side angular? If not, you should decide whether it can be (there shouldn't be a reason not to), or you need to reply to the pre-flight OPTIONS request from your server that you are seeing.
I had the very same issue with my Rails + Angular app. I had my cors well set up in my rails app but still nothing, I still got a 404 not found in the angular app. This could be the reason:
Perhaps you have "angular-in-memory-web-api": '0.x.x' in your package.json and also imported in your app.module.ts, as InMemoryWebApiModule and InMemoryDataService. These apparently intercept all calls to an API preventing them from ever reaching your back-end server. When I Removed those dependencies and their declarations, all of a sudden my app started working normally!
Look at this answer for more information.

Resources