Enable CORS for AngularJS application on YEOMAN - ruby-on-rails

I am trying to redirect my application to a payment gateway using $http post method
below is the code:
$http.post("payment api",paymenttrans,
{headers: { 'content-type':'application/json; charset=utf-8',
'X-App-Token':payment token }})
.then(function (success){
//some code
},function (error){
//some code
});
grunt file is as below :
grunt.initConfig({
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: 'localhost',`enter code here`
livereload: 35729
},
livereload: {
options: {
open: true,
middleware: function (connect) {
return [
connect.static('.tmp'),
connect().use(
'/bower_components',
connect.static('./bower_components')
),
connect().use(
'/app/styles',
connect.static('./app/styles')
),
connect.static(appConfig.app)
];
}
}
},
test: {
options: {
port: 9000,
middleware: function (connect) {
return [
connect.static('.tmp'),
connect.static('test'),
connect().use(
'/bower_components',
connect.static('./bower_components')
),
connect.static(appConfig.app)
];
}
}
}
})
I am getting an error stating that :
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at Payment page. (Reason: missing token ‘content-type’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel).
Need help on this with Grunt configuration or server configuration
Web server : NGINX.
Application Server : Puma.
Language : Ruby on Rails.
I have tried solutions like https://gist.github.com/Vp3n/5340891 which didn't help my problem.

Related

Nuxt auth-next with keycloak CORS problem

Versions:
keycloak 12.0.2
nuxt: 2.14.6
nuxt/auth-next: 5.0.0-1622918202.e815752
Configs:
nuxt.config.js
auth: {
strategies: {
keycloak: {
scheme: '~/plugins/keycloak.js',
endpoints: {
authorization:'https://keycloak.bgzchina.com/auth/realms/bgzchina/protocol/openid-connect/auth',
token:'https://keycloak.bgzchina.com/auth/realms/bgzchina/protocol/openid-connect/token',
userInfo: "https://keycloak.bgzchina.com/auth/realms/bgzchina/protocol/openid-connect/token",
logout:'https://keycloak.bgzchina.com/auth/realms/bgzchina/protocol/openid-connect/logout',
},
responseType: 'id_token token',
clientId: 'centuari-portal-fe',
scope: ['openid'],
}
},
redirect: {
login: '/login',
logout: '/logout',
callback: '/callback',
home: '/',
}
},
router: {
middleware: ['auth']
},
due to a issue with current version nuxt/auth-next, I created a custom scheme by extending oauth2
/plugin/keycloak.js
import { Oauth2Scheme } from '~auth/runtime'
function encodeQuery(queryObject) {
return Object.entries(queryObject)
.filter(([_key, value]) => typeof value !== 'undefined')
.map(([key, value]) => encodeURIComponent(key) + (value != null ? '=' + encodeURIComponent(value) : ''))
.join('&')
}
export default class KeycloakScheme extends Oauth2Scheme {
logout() {
if (this.options.endpoints.logout) {
const opts = {
client_id: this.options.clientId,
post_logout_redirect_uri: this._logoutRedirectURI
}
const url = this.options.endpoints.logout + '?' + encodeQuery(opts)
window.location.replace(url)
}
return this.$auth.reset()
}
}
but when doing login, browser will block the token request due to CORS. keycloak server response for the preflight specify allowed method is POST, OPTIONS, but auth-next use GET to fetch token.
Is there any work around ?
You need to add/register the url into keycloak admin dashboard.
Go to keycloak admin dashboard
Menu Clients => select the client
On Settings tab, scroll down the page and find Web Origins. Add your frontend url (nuxt url) on it. Don't forget to add into Valid Redirect URIs too.

Does anybody know how to proxy the index.html in webpack-dev-server or similar?

I have MVC as my backend. MVC controllers/views have _StartPage.cshtml, _Layout.cshtml (They are combined to form _index.cshtml).
So, I need to use webpack dev server proxy to fetch the index.html from backeend server. Is there any way to do it?
So far this is what I've come up with
devServer: {
historyApiFallback: true,
index: '',
contentBase: "./",
port: 8000,
proxy: [{
//Only works for api, index.html does not
context: ['/index.html', '/api'],
target: 'http://localhost',
pathRewrite: { '^/api': '/TestApp/api' }
}]
},
I'm open to use any other client server beside webpack-dev-server if that solves the problem?
Please note that this will be used only in Development Not in production.
I think you want a different entry for each path. Something like this maybe?
devServer: {
contentBase: './',
port: 8000
proxy: {
'/index.html': {
target: 'http://localhost/',
pathRewrite: { '^/': 'TestApp/index.html' },
},
'/api': {
target: 'http://localhost/',
pathRewrite: { '^/api': '/TestApp/api' }
},
},
}
How about your project structure?
The webpack-dev-server must be used in development mode, after build and deployed, you need to change the api url for production mode.
I'm a front-end and I meet similar problem, I solve it by DefinePlugin that could change api in different mode.
My webpack like this:
├webpack.common.js
├webpack.dev.js
├webpack.prod.js
webpack.common.js
devServer: {
// contentBase: 'dist/',
historyApiFallback: true,
watchOptions: { aggregateTimeout: 300, poll: 1000 },
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
},
proxy: {
'/': {
target: 'xxxxxxxxxxxx/website/',//url
changeOrigin: true,
secure: false,
}
}
},
webpack.dev.js
plugins:[
new webpack.DefinePlugin({
'SERVICE_URL': JSON.stringify('')
})
]
webpack.prod.js
plugins:[
new webpack.DefinePlugin({
'SERVICE_URL': JSON.stringify('https://xxx.api.com/') //real api
})
]
fetch/ajax code
console.log(SERVICE_URL)
$.ajax({
url: SERVICE_URL+'api/%E6%AD%A6%E6%BC%A2%E8%82%BA%E7%82%8E_%E5%8F%B0%E5%95%86_simple.json',
...
This is my solution, I hope it could give some inspiration.

neo4j basic auth for client http requests

Trying to get adagio with neo4j to run but i dont know how to format login/password in the adagio config file:
define(function () {
'use strict';
return {
client: {
apiEndpoint: "http://127.0.0.1:7474/db/data",
authBasic: "Basic neo4j/neo4j",
},
},
}
Any hints are welcome.
I think it is right in front of you, not sure though, neo4j is just the default username and password
define(function () {
'use strict';
return {
client: {
apiEndpoint: "http://127.0.0.1:7474/db/data",
authBasic: "Basic user/password",
},
},
}

loopback.io rest connector - how to pass through oAuth token

Using loopback, I have created a connection to an existing API using the REST connector, which is working well. I would however like to pass through the oAuth token coming from the client.
I can get hold of the oAuth token by grabbing ctx.req.headers.authorization from the Model.beforeRemote method, but can't seem to figure out a way of passing it to the REST connector as a new header.
I've tried a couple of things:
Adding a hook using Model.observe (but this doesn't seem to fire with the REST connector).
Using a template with an authorization field - but have not been able to get this working correctly.
Any ideas appreciated.
With the connector below you should be able to pass the OAuth token into the function (as first parameter in the example). Does something like this not work for you?
{
connector: 'rest',
debug: false,
options: {
"headers": {
"accept": "application/json",
"content-type": "application/json",
"authorization": "{oauth}"
},
strictSSL: false,
},
operations: [
{
template: {
"method": "GET",
"url": "http://maps.googleapis.com/maps/api/geocode/{format=json}",
"query": {
"address": "{street},{city},{zipcode}",
"sensor": "{sensor=false}"
},
"options": {
"strictSSL": true,
"useQuerystring": true
},
"responsePath": "$.results[0].geometry.location"
},
functions: {
"geocode": ["oauth", "street", "city", "zipcode"]
}
}
]}
Wanted to answer this, and build on Bryan's comments. Firstly, in datasources.json, you'll want to setup the REST connector:
{
"name": "connect",
"connector": "rest",
"debug": "true",
"operations": [
{
"template": {
"method": "GET",
"url": "http://server/api",
"headers":{
"authorization": "Bearer {token}"
}
},
"functions": {
"get": ["token"]
}
}
]
}
As Bryan covered, it possible to put the auth header in each call, or at the root of the connector.
Secondly, and this is the bit I was stuck on, in order to pass the token to the API call from a model, it's required to generate a remote method that passes the token as a query parameter. This is what it looks like in this example:
module.exports = function (Model) {
Model.disableRemoteMethod('invoke', true);
Model.disableRemoteMethod('get', true);
Model.call = function (req, cb) {
var token = req.token;
Model.get(token, function (err, result) {
cb(null, result);
});
};
Model.remoteMethod(
'call',
{
http: {path: '/', verb: 'get'},
accepts: [
{arg: 'req', type: 'object', http: {source: 'req'}}
],
returns: {
root: true
}
}
);
};
Notice how the req argument is required in order to provide the request to the model. You also notice that I've disabled the original get and invoke methods (replacing it with a more REST-friendly resource).
Finally, you'll need to get the token into the request. For this, it's easy enough to use some middleware. Here's an example from server.js:
app.use('/api', function (req, res, next) {
oidc.authenticate(req, function (err, token) {
if (err) {
return res.send({status: 401, message: err});
}
req.token = token;
next();
});
});
In the above example, I'm using an internal OIDC provider to validate the token, but of course, you can use anything.

Getting No 'Access-Control-Allow-Origin' with Swagger and Foreman Rails server

I have my server currently running at 0.0.0.0:5100. When I try to access my Swagger docs, I get the following error in the console:
XMLHttpRequest cannot load http://0.0.0.0/api/v1/types.json. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://0.0.0.0:5100' is therefore not allowed access.
I am wondering why is that happening. Here is my Swagger configuration in index.html:
$(function () {
window.swaggerUi = new SwaggerUi({
url: "/api-docs.json",
dom_id: "swagger-ui-container",
supportedSubmitMethods: ['get', 'post', 'put', 'delete'],
onComplete: function(swaggerApi, swaggerUi){
log("Loaded SwaggerUI");
if(typeof initOAuth == "function") {
/*
initOAuth({
clientId: "your-client-id",
realm: "your-realms",
appName: "your-app-name"
});
*/
}
$('pre code').each(function(i, e) {
hljs.highlightBlock(e)
});
},
onFailure: function(data) {
log("Unable to Load SwaggerUI");
},
docExpansion: "none"
});
Have you enabled CORS support for your web-service? The Swagger documentation calls out that CORS support is required for that to work. The error message you are getting is the exact same message I was getting on my Grails project before I added CORS support.
Allow-Control-Allow-Origin: * extension on chrome store added into the browser.
Note: Once you done with work disable this options becasue youtube will not work with enable option.

Resources