Problem description : I have built a ionic app which uses JIRA rest api to fetch issue (GET data), create issue (POST data). I always get CORS error's like preflight request did not succeed or same origin policy which are expected when we use ionic serve but the same is not working when I build and release the signed apk.
My ionic server runs on localhost:8100 (ionic version -4) &
Jira server runs on localhost:8089 (JIRA version - core 7)
What I have done so far :
followed the proxy approach as mentioned in ionic blog --No success
enabled CORS filter plugin in JIRA server and whitelisted ionic server --No success
Added headers for Allow control origin -- No success
Build the apk file using --prod release signed and tried the same on device --No sucess
Here is my auth.ts file reference if any-one can help and advise here about what I am doing wrong here.
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { AuthProvider } from '../auth/auth';
import { Issue } from '../../models/issue'
#Injectable()
export class JiraProvider {
apiVersion: string = '2'; // The API version we want to use
jiraInstanceUrl: string = 'http://localhost:8089' // The Jira instance URL
urlString: string = `${this.jiraInstanceUrl}/rest/api/${this.apiVersion}`; // Concat those together
constructor(
public http: HttpClient,
public auth: AuthProvider
) {
}
// Authenticate the user against Jira's profile endpoint.
public authenticateUser(username: string, password: string): Observable<Object> {
return this.http.get(`${this.urlString}/myself`, {
headers: new HttpHeaders()
.append('Authorization', `Basic ${btoa(username + ':' + password)}`)
.append("Access-Control-Allow-Origin","*")
});
}
// Get issue details based on the provided key.
public getIssue(key: string): Observable<Issue> {
return this.http.get<Issue>(`${this.urlString}/issue/${key}`, {
headers: new HttpHeaders()
.append('Authorization', `Basic ${this.auth.getAuthString()}`)
.append("Access-Control-Allow-Origin","*")
});
}
public getAllIssue():Observable<any> {
return this.http.get(`${this.urlString}/search?jql=project=PM`,{
headers: new HttpHeaders()
.append('Authorization', `Basic ${this.auth.getAuthString()}`)
.append("Access-Control-Allow-Origin","*")
});
}
public postIssue(data):Observable<any>{
return this.http.post(`${this.urlString}/issue`,JSON.stringify(data),{
headers: new HttpHeaders()
.append('Authorization', `Basic ${this.auth.getAuthString()}`)
.append('Content-Type','application/json')
.append("X-Atlassian-Token", "no-check")
.append("User-Agent", "xx")
.append("Access-Control-Allow-Origin","*")
});
}
}
Added screenshot as per request(please not I changed the JIRA server intentionally to 8089 updated the question accordingly)
I soved this issue by using a CORS proxy in a container (Docker) for when you need to Access-Control-Allow-Origin: *`! this acts like a proxy https://github.com/imjacobclark/cors-container and now I am able to route the requests.
Hope it helps others !!
Related
Is it possible to set request headers in Protractor?
In the following post (2014), Protractor confirmed that currently they don't have any way to do this (as protractor was not designed to interact with under-the-hood things.
here
Has anyone found out a way how to do this?
Thanks in advance :)
I had the same problem so I implemented a simple proxy to inject headers in the requests. I published it on npm repository. You can find it here https://www.npmjs.com/package/headers-injection-proxy
Very easy to use:
header-injection-proxy -p 3000 -t "https://www.google.com" -h "headers.json"
At that point you just send the requests to the proxy instead of the real server
You can use an external library like request. For me it worked as a charm with Protractor:
https://github.com/request/request#custom-http-headers
EDIT:
Here you have an example of implementation. It uses request-promise
import {browser} from 'protractor';
import {put} from 'request-promise';
import {ADMIN_URL} from '../data/definitions/urls';
export class CreateUser {
public setRoles(username: string, roles: string[]) {
return this.getUserId(username).then((userId) => {
const data = {
url: `${ADMIN_URL}/user/${userId}/role`,
headers: {
Authorization: browser.params.token
},
body: roles,
json: true,
rejectUnauthorized: false
};
return put(data);
});
}
}
I'm working on a Laravel application that uses React and Redux on the client side, with the React preset and Mix. I've decided to try out GraphQL for the API rather than the usual REST API approach and it's working OK so far. However, I've now got stuck.
I'm using Apollo as my HTTP client since it's built for working with GraphQL. In the past I've used JWT Auth for securing APIs, so naturally I've gone for that approach here too, since implementation is just a case of adding an appropriate header. I've followed the instruction on setting headers with Apollo, but the headers aren't getting set. Here's the JS file in question:
import LinkList from './components/LinkList';
import React from 'react';
import ReactDOM from 'react-dom';
import {Container} from './container';
import {createStore} from 'redux';
import reducer from './reducer';
import {Provider} from 'react-redux';
import {fromJS} from 'immutable';
import ApolloClient from 'apollo-boost';
import gql from 'graphql-tag';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { InMemoryCache } from 'apollo-cache-inmemory';
const httpLink = createHttpLink({
uri: window.initialData.graphql_route
});
const authLink = setContext((_, { headers }) => {
const token = window.initialData.jwt;
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
client.query({
query: gql`{
links {
id
title
link
}}`
}).then(result => console.log(result));
const store = createStore(
reducer,
fromJS(window.initialData),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
if (document.getElementById('list')) {
ReactDOM.render(
<Provider store={store}>
<Container />
</Provider>,
document.getElementById('list')
);
}
I populate window.initialData in the view, and that contains the necessary data, including the JWT token as window.initialData.jwt. Setting a breakpoint inside the definition of authLink does nothing, implying that it never gets called.
Any idea what's gone wrong? I've followed the examples in the documentation pretty closely, so all I can think of is that they might be put of date.
Info: Don't save your token in the localStorage Is it safe to store a JWT in localStorage with ReactJS?
You are using the ApolloClient from 'apollo-boost', but your token configuration is for another ApolloClient, the { ApolloClient } from 'apollo-client'.
If you want to save the token using the ApolloClient from apollo-boost:
const client = new ApolloClient({
uri: ...,
request: async operation => {
const token = localStorage.getItem('token');
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : ''
}
});
}
});
Apollo Boost migration
Using Ionic 4.4.0 and aws-sdk 2.157.0. I'm trying to create an S3 bucket from my local web browser, but am running into CORS problems when attempting to run the following code, method createBucketByCompanyKey():
import { Injectable } from '#angular/core';
import * as AWS from 'aws-sdk';
#Injectable()
export class AwsProvider {
private accessKeyId:string = 'myAccessKey';
private secretAccessKey:string = 'mySuperSecret';
private region:string = 'us-east-1';
constructor() {
AWS.config.update({accessKeyId: this.accessKeyId, secretAccessKey: this.secretAccessKey, region: this.region});
}
createBucketByCompanyKey(companyKey){
let s3 = new AWS.S3();
let params = {
Bucket: companyKey,
CreateBucketConfiguration: {
LocationConstraint: this.region
}
};
s3.createBucket(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
}
}
This gives me the error
Failed to load https://s3.amazonaws.com/-KwzdjmyrHiMBCqHH1ZC: Response
to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8100' is therefore not allowed
access. The response had HTTP status code 403.
Which led me to this post here after several hours of googling. It appears I need to run ionic through a proxy. I've also tried changing my "path" to http://localhost:8100, but stuck I remain.
{
"name": "MyApp",
"app_id": "",
"type": "ionic-angular",
"integrations": {},
"proxies": [
{
"path": "/",
"proxyUrl": "https://s3.amazonaws.com/"
}
]
}
I've also come across posts telling my to download a Chrome extension that disables CORS, but that didn't work either.
Any ideas on how to setup this proxy to work with AWS' SDK?
Forget the proxies. For Mac, enter in the following in the terminal to open a Google Chrome browser with CORS disabled.
open -a Google\ Chrome --args --disable-web-security --user-data-dir
Compliments of this post.
I have some problems with Angular 2 http get request in a ionic 2 application.
In fact I have a website (made with the Jalios CMS) which is running currently with an Apache tomcat on localhost:8080 and I want to access data from my ionic app with RESTful Web services. To access to this website the users need to log in, and their passwords can contain special charactere like #,#.:?
When I use the cURL command, I can access data without any problems. Data are returned in xml.
curl -u username:p#ssword http://localhost:8080/jcms/rest/data/Article
However in my ionic 2 application I have the following errors:
OPTIONS http:/ /localhost:8080/jcms/rest/data/Article 401 (Non-Autoris%E9). polyfills.js:3
XMLHttpRequest cannot load http:/ /localhost:8080/jcms/rest/data/Article. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http:/ /localhost:8100' is therefore not allowed access. The response had HTTP status code 401. (index):1
ERROR Response {_body: ProgressEvent, status: 0, ok: false, statusText: "", headers: Headers…}. core.es5.js:1084
my http provider: rest-service.ts
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class RestService {
constructor(public http: Http) {
console.log('Hello RestService Provider');
}
httpGet(username: string, password: string, resource: string){
let url = 'http://localhost:8080/jcms/rest/data/' + resource;
let headers: Headers = new Headers();
headers.append("Authorization", "Basic " + btoa(username + ":" + password));
return this.http.get(url, {headers: headers});
}
}
my Ionic page (component): home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import {RestService} from "../../providers/rest-service";
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
result: Array<any>;
constructor(public navCtrl: NavController, private restService: RestService) {
this.restServiceGet();
}
restServiceGet(){
this.restService.httpGet('username', 'p#ssword', 'Article')
.map(res => res.json())
.subscribe(data => this.result = data);
}
}
Normally all have been correctly imported in the app.module.ts file. I also try to change the special character by URL Encoding (%40 for #), and replace the btoa directly by the base 64 equivalence of username:p#assword.
Can you help me to correct this errors? Especially the 401 unauthorized because I d'ont understand why it happen whereas I implemented the headers with the basic authentification. Where are my mistakes?
Thank you
I am facing issue in my Ionic app . Rest api is written in Scala which is working properly in Website and Ionic app on browser and on postman . But it is not working on App. I am facing 403 issue when i am hitting that API.
I tried to update scala config file
cors {
pathPrefixes = ["/api"]
}
Now it is working fine in app but not in browser , What to do ? Is it issue from API end or Ionic code end? My code is as following
let params = {"vendor._id":"1"};
let headers = new Headers({
"Content-Type": "application/json"
});
let options = new RequestOptions({
headers: headers
});
this.http.post('apiurl',params, options)
This is Play framework issue with Cordova. The following link will explain it:
https://forum.ionicframework.com/t/ionic-http-request-with-403-error-on-ipad-device/50269/3
Reason:
Cordova sends a request through having header Origin: file://…
You can check this link to deal with that
Play! 2.4: How to allow CORS from origin file://
Remove default course filter which you import from Play framework and write your condition based filter:
import play.api.Logger
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.mvc._
import play.mvc.Http
/**
* Allow CORS from anywhere, any method
*/
class CORSFilter extends EssentialFilter {
def apply(nextFilter: EssentialAction) = new EssentialAction {
def apply(requestHeader: RequestHeader) = {
nextFilter(requestHeader)
.map { result =>
if (requestHeader.method.equals("OPTIONS")) {
Results.Ok.withHeaders(
Http.HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN -> "*",
Http.HeaderNames.ACCESS_CONTROL_ALLOW_HEADERS -> "Access-Control-Allow-Origin,X-Requested-With, Accept, Content-Type,application, idUser, access-control-allow-methods, token, access-control-allow-credentials, Authorization",
Http.HeaderNames.ACCESS_CONTROL_ALLOW_METHODS -> "HEAD,GET,POST,PUT,PATCH,DELETE")
} else {
result.withHeaders(
Http.HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN -> "*",
Http.HeaderNames.ACCESS_CONTROL_ALLOW_HEADERS -> "X-Requested-With, Accept, Content-Type",
Http.HeaderNames.ACCESS_CONTROL_ALLOW_METHODS -> "HEAD,GET,POST,PUT,PATCH,DELETE",
Http.HeaderNames.ACCESS_CONTROL_EXPOSE_HEADERS -> "X-Custom-Header-To-Expose")
}
}
}
}
}