Waterlock, Sails, Angular JWT token gives 403 from browser - angularjs

backend: Sails app w/ Waterlock, Waterlock-local-auth
frontend: An angular app
I'm running into a issue where postman works fine, gets JWT from /user/jwt all good and dandy but whenever I login through the browser and then attempt to hit /user/jwt it gives 403 forbidden. Any clues?
I have CORs enabled for all origins on all routes.
Any help would be appriciated!

To save some time for novices like me:
$http won't be passing the session data with the request, so Sails/express server doesn't know which 'session' the /user/jwt request is being made from and hence giving 403, as it should. I guess Postman handles this for you automagically.
Added this to my angular config:
config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.withCredentials = true;
}]).

Related

React App + Spring Boot - JWT auth token inside a cookie is not set in Chrome

I'm trying to configure Spring Boot to set-cookie containing JWT auth token following a sign-in request from my react app, and then the expectation is that the browser will automatically set this cookie to all requests as specified by the cookie path. The behaviour is ok on my friend's environment - same code, Chrome browser, different machine. I tried clearing node_modules, mvn clean install, also tried different browsers Chrome and FireFox, no success.
Here is the all the relevant code (let me know if I'm missing something else important)
React is running on localhost:3000
Spring Boot is running on localhost:8080
There is a proxy in the package.json
"proxy": "http://localhost:8080",
To test the auth flow we are issuing a sign-in request from the sign-in form (react), the request is successfully proxied to port 8080 and the response from the server is successfully returning the JWT token as part of an auth cookie. The cookie is specified to the /api path. Network request as seen in Chrome below:
Immediately after the login, the react app is issuing a second HTTP request to the back-end, but a break-point on the server shows no cookies are passed from the browser as part of this request. The request is to http://localhost:3000/api/user.
In the front-end we are using fetch to make that request and it looks like this:
fetch("/api/user, {
credentials: "same-origin"
})
Just for additional context this is how we return the original cookie from the server, upon a successful login:
#PostMapping("/signin")
public ResponseEntity signin(#RequestBody AuthenticationRequest data, HttpServletResponse response) {
try {
String username = data.getUsername();
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, data.getPassword()));
User user = (User) authentication.getPrincipal();
String token = jwtTokenProvider.createToken(user);
final Cookie cookie = new Cookie("auth", token);
cookie.setSecure(!environment.acceptsProfiles(Profiles.of("dev")));
cookie.setHttpOnly(true);
cookie.setMaxAge(Integer.MAX_VALUE);
cookie.setPath("/api");
response.addCookie(cookie);
return ok(buildUserResponseObject(user));
} catch (AuthenticationException e) {
throw new BadCredentialsException("Invalid username/password supplied");
}
}
Is there anything wrong with our approach? What could be preventing my browser from passing on the auth cookie?
Oh this is embarrassing...
The issue was this line
cookie.setSecure(!environment.acceptsProfiles(Profiles.of("dev")));
!environment.acceptsProfiles(Profiles.of("dev")) was evaluating to true and it was causing the cookie to be only passed if the connection is secure, which it wasn't because it was localhost. Mystery solved.

CORS request did not succeed - react

I make this API request , using axios in ReactJS
axios.post(`${API_URL}/valida_proximo`, {
id: images.map(image => image.id)
},
getAxiosConfig())
// this.setState({ images, loadingAtribuiImagens: false})
}
It works really well in Google Chrome, but on Firefox I receive an error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:5000/valida_proximo. (Reason: CORS request did not succeed).[Learn More]
What can I do?
This is my API
#blueprint.route('', methods=['POST', ])
#jwt_required()
def index():
if request.json:
id_usuarioImagem = request.json.get('id')
imagens_selecionadas =
UsuarioImagem.query.filter(UsuarioImagem.id.in_(id_usuarioImagem)).all()
if imagens_selecionadas:
for imagem_selecionada in imagens_selecionadas:
imagem_selecionada.batido=True
db.session.commit()
return 'ok', 200
return 'error', 400
CORS errors are usually associated with cross domain requests and something not configured to accept a request on the recipient side of the request. The fact that chrome is working but firefox doesn't seems rather strange.
This was a method I used:
Open Firefox browser and load the page.
Perform the operation which is throwing Cross Origin Request Security (CORS) error.
Open firebug and copy the URL which is throwing Cross Origin Request Security (CORS) error.
Load the same URL in another tab in same Firefox browser.
Once you open the URL in another tab will ask you to add the certificate.
After adding the certificate will resolve Cross Origin Request Security (CORS) error and now you will not be getting this error.
I'm not too familiar with Axios, but it looks like you're making a post request from your React to your Flask backend. If the front-end and the backend are on different ports (like your Flask seems to be on PORT 5000), then you're making a CORS request.
With CORS, depending on what you're posting, you might need to include some Access-Control headers in your Flask response object. You can do this either manually, or just pip-installing and using the 'flask-cors' package. Import the package into your app factory and use it like so (see their docuementation for more info):
from flask_cors import CORS
def create_app(test_config=None):
app = Flask(__name__, instance_relative_config=True)
CORS(app)
The request might also get 'preflighted' with an 'OPTIONS' request, also depending on the nature of your POST. More information would be helpful
This is a bug in firefox.
if you follow the link (MDN) in the error msg . you will find:
What went wrong?
The HTTP request which makes use of CORS failed because the HTTP connection failed at either the network or protocol level. The error is not directly related to CORS, but is a fundamental network error of some kind.
which i read as the connection failed and not a problem with CORS settings.
you will just have to ignore the error message until firefox gets it fixed.
The error has something to do with refreshing the page and long polling requests or service workers and polling requests.
If anyone sees this question again, I had this problem because I made a request to https://url instead of http://url

Angular $http.post not working, works using postman

I've created an Ionic app which calls an API to post the user's current location.
The request works as follows:
POST: http://mywebsite.com/api/Patients/AddLocation/17
with body:
{
"Latitude": 51.3753786,
"Longitude": -0.0833691
}
However, the following code in my Ionic app does work:
$http.post('http://mywebsite.com/api/Patients/AddLocation/' + $scope.id, data)
.success(function () {
console.log('Updated location');
})
.error(function (error) {
console.log('Error updating location');
console.log("Error: " + error);
});
In which 'data' is the same as the body above.
Any ideas why this isn't working?
UPDATE:
Here's a couple of screenshots of the network request:
Network request available at imgur RWNDF.png
Postman request
It happens if you have not enabled cors in your server.
enable cors in you server.
even if you dont enable cors,
get method will work peerfectly if you have enabled cors using any extension in chrome.
It's because of CORS. Enable cros from the server end and the a header will be set in HTTP Access-Control-Allow-Origin: * .
If your server app is an expressjs app, use below code to enable CORS
var cors = require('cors');
.....
app.use(cors());
Else use chrome extension Allow Cross Origin Request
This should solve the problem
After comparing this to a sister app which uses the same API and works, the only difference I could see was that a few of the plugins were different.
To remedy this I deleted the plugins folder and the platforms folder, re-added android and just the plugins I need, it now works. I guess it's maybe some bug I created by using the wrong mixture of plugins.
A very unsatisfying answer, but all requests work now!

AngularJS Http Request return 401 from a SailsJS server with Electron

I'm building a Electron App. Any request I make with Angular running on the Electron App return with unauthorized.
I already checked for the poilicies from Sails, disabled all policies. If I make a request for the same url from Postman or even Chrome it works ok.
$http.get(CONFIG.API + 'auth/login', $scope.login).then(function (data) {
console.log(data);
});
It's 100% config/cors.js issue. Make sure you have uncommented this line of code.
allRoutes: true,

GET request throws error after app implemented SSL: Mixed Content: This request has been blocked; the content must be served over HTTPS"

Mixed Content: The page at 'https://www.example.com/dashboard' was
loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint
'http://api.example.com/inventory/10/'. This request has been blocked;
the content must be served over HTTPS.
We have this Angular web app that runs with Flask on the back-end.
Everything was working fine until we implemented SSL. Afterwards, we keep getting this strange error everywhere.
Now, the $http.get request in my dashboard.js is definitely calling "https://api.example.com/inventory/10" in the code below and yet the error is claiming that we are trying to request "http" instead.
$http.get($rootScope.baseUrl+'/inventory/' + item.id)
where rootScope.baseUrl is "https://api.example.com".
It's really weird because some GET requests ARE going through from our web application to our back-end, but some requests are throwing this weird error.
Here's the header that gets an error in our Network tab of the console in chrome.
Request URL:https://api.example.com/inventory/10 Request Headers
Provisional headers are shown Accept:application/json, text/plain, /
Origin:https://www.example.com
Referer:https://www.example.com/dashboard
It was a weird case that came down to removing a forward slash from the end of a URL fixing everything. Somehow, whenever we made a GET request using $http in Angular like baseurl + inventory.id + "/", it would make a http request but as soon as remove that slash, it would make the https request correctly.
Still so confused
I think the root of the problem is in server redirects. I was able to resolve same issue with SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') setting for Django (its running behind AWS balancer). Here is documentation.

Resources