Using Axios as an Alternative to request in nodejs - flutter

I am building a flutter application that requires oauth 1 authorization for one of the third party services I am using. Because flutter oauth 1 package is restricted I decided to use the oauth 1 package that npm provides. This is the code that is used to access the user generated access token from the site.
I previously used request to make a call to the api endpoint first, to access the token and secondly to use the token recieved to make another call to a different resource endpoint
How can I use axios to make the same request, emphasis on the fact that each request needs a hmac-sha1 signed signature in the header.
Thank you.
consumer: {
key: CONSUMER KEY,
secret: CONSUMER SECRET,
},
signature_method: 'HMAC-SHA1',
hash_function(base_string, key) {
return crypto
.createHmac('sha1', key)
.update(base_string)
.digest('base64')
},
})
const request_data = {
url: 'https://www.instapaper.com/api/1/oauth/access_token/',
method: 'POST',
data: { x_auth_username : USERNAME , x_auth_password : PASSWORD , x_auth_mode : 'client_auth' },
}
request(
{
url: request_data.url,
form: request_data.data,
method: request_data.method,
headers: oauth.toHeader(oauth.authorize(request_data)),
},
function(error, response, body) {
// Process your data here
console.log(error);
console.log(response);
console.log(body);
}
)

Finally found the answer for this link to the issue created on github
https://github.com/axios/axios/issues/2771

Related

How to tell auth0 im authenticated in req.rest file

So I want to make a post request to my nextJS backend and the route i am making the req to a protected route so in my Rest client file (req.rest) I need to tell auth0 im authenticated but i do not know how to do that.
req.rest
POST http://localhost:3000/api/video
Content-Type: application/json
Authorization: Bearer cookie
{
"title": "Video",
"description": "Video description"
}
api/video.js
import { withApiAuthRequired, getSession } from "#auth0/nextjs-auth0";
import Video from "../../database/models/Video";
export default withApiAuthRequired(async function handler(req, res) {
if (req.method === "POST") {
try {
const { user } = getSession(req, res);
const newVideo = new Video({
title: req.body.title,
description: req.body.description,
ownerId: user.sub,
});
await newVideo.save();
res.json(newVideo);
} catch (error) {
res.status(500).json({ error: error.message });
}
}
});
I'm not sure I understand your question. Your API should determine if the user is authenticated by validating the bearer token value you are passing through the Authorization request header, you shouldn't need to pass additional data as separate parameters to authorize the API. If you do need additional data to determine if the user is authorized to consume the API, that should be included inside of the bearer token as a claim.
So I haven't really found a solution but I do have a workaround which is to just make new page on the frontend for requests and send the requests from there.

Token is generated at the endpoint but does not arrive on the page

I want to create a website with Svelte/Kit and use JWT.
I have found instructions on the internet, for example:
Svelte JWT Authentication https://morioh.com/p/1d95522418b2
SvelteKit Session Authentication Using Cookies https://www.youtube.com/watch?v=bG7cxwBMVag
But unfortunately no instructions for Svelte Kit and JWT. So I tried it myself.
The token is generated at the endpoint, but does not arrive on the page (or is not callable). I suspect that some setting in the headers is wrong, but can't figure out what is wrong. This is my highly simplified test environment:
(1) I call the endpoint login.js from the page index.svelte. For testing, I omit checking email and password and send JWT right back. Data arrives, but I don't see the JWT.
(2) The JWT should be sent to another endpoint. What is the best way to do this?
The "page" index.svelte (simplified):
<script>
let email="", password="";
const doLogin = async () => {
const response = await fetch("/auth/login", {
method: 'POST',
headers: {
"Content-Type": "application/json",
},
credentials: 'include',
body: JSON.stringify({
email,
password
})
});
if (response.status == 200) {
const { done, value } =
await response.body.getReader().read();
await console.log("done, value=", done,
JSON.parse(new TextDecoder("utf-8").decode(value)));
await console.log("headers=", response.headers);
}
}
</script>
<h1>Welcome to MyAuth</h1>
<input type=email bind:value={email}/><br/>
<input type=password bind:value={password}/><br/>
<button on:click={doLogin}>Submit</button>
The "endpoint" login.js (simplified):
import jwt from "jsonwebtoken";
export function post(request, context) {
const token = jwt.sign({
data: { text: "test" },
"topsecret",
});
const response = {
status: 200,
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${token}`,
},
body: {
passwordOk: true,
}
};
return response;
}
The console shows:
done, value= false {passwordOk: true}
index.svelte:59 headers= Headers {}
index.svelte:44 Fetch finished loading: POST "http://localhost:3000/auth/login".
doLogin # index.svelte:44
I think you are mixing up the two major parts to authentication:
Requesting/sending credentials.
Using those credentials to access protected content.
Authorization: Bearer ${token} is normally sent from the (browser) client to the server to request access to protected content. So right now, your server is asking the client for permission. This doesn't make sense.
Instead, the login endpoint should send the token via:
Set-Cookie header in the login endpoint.
The body of the response (where passwordOk is).
Set-Cookie causes the browser to send this value as a cookie with every future request. The server can check for this cookie value before serving protected content. This can be more secure because you can send an HTTP only cookie.
If the token is sent in the body of the response to login the client should send the token in future requests with the Authorization: Bearer ${token} header. The server can then check for this header before serving protected content.

how can access to an API which is have a token with Axios in vuejs?

I have an API that has a JSON file, I gonna get information from that with Axios but it has Token and I don't know how can use it anybody can help me?
here it's API
‫‪https://api.nytimes.com/svc/movies/v2/reviews/picks.json‬‬
I try this but its didn't work and gave me error 401 and this
GET https://api.nytimes.com/svc/movies/v2/reviews/picks.json%E2%80%AC%E2%80%AC 401 (Unauthorized)
<script>
import axios from "axios";
export default {
data() {
return {};
},
methods: {
async getDataFromApi() {
const res=await axios.get("https://api.nytimes.com/svc/movies/v2/reviews/picks.json‬‬");
console.log(res.data)
},
},
};
</script>
please, someone helping me
401 Error means you not authenticated. you must add a token in axios authorization header and send it with your HTTP request.
const res = await axios.get('https://api.nytimes.com/svc/movies/v2/reviews/picks.json', {
headers: {
authorization: 'my secret token'
}
});
This is the hard code way, for more efficiency, you must define interceptors for axios to send the token with every HTTP request. see this: https://gist.github.com/srph/38f67a10e991b6cb2d83

Want to integrate auth0 in ionic using capacitor

I want to integrate auth0 in my ionic4 application. I think I am supposed to have separate implementation of auth0 for web(pwa) and android/ios. I am using capacitor and I am not able to find an appropriate solution. Is there any way in which I can maintain a single code base for all platforms?
My solution is to use Auth0 API to handle appropriate actions: Sign Up, Sign In, Sign Out and Renew Token. You can find detailed description for lots of actions at Auth0 docs.
So, I managed to create utility functions like the following one:
import environment from 'environment';
import * as constants from './constants';
const signUp = async (email: string, password: string): Promise<any> => {
const resonse = await fetch(constants.AUTH0_ENDPOINTS.SIGN_UP, {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
body: JSON.stringify({
client_id: environment.AUTH0_CLIENT_ID,
connection: constants.AUTH0_DATABASE_NAME,
email,
password,
}),
});
return resonse.json();
};
export default signUp;
Also I implemented Auth class that is responsible for session operating, refreshing token and silent auth.

Jhipster + REST client + authentication

I need to understand how to authenticate a REST client (could be Paw, could be an android app, an iOs app using AFNetworking with jHipster and I think, more in general, with spring-boot of which I am no expert).
While I am able to obtain a token when logged in a browser, and subsequently use this token in the following requests, I do not understand how I can authenticate in the first place using RESTful best practices.
For example, in Paw.app, I can pass a Basic authentication, or Oauth2, but I don't understand how to get the session token simply authenticating as I do on a web browser.
Similarly, in AFNetworking I am able to pass basic authentication, e.g.
NSString*auth=[NSString stringWithFormat:#"%#:%#", #"admin", #"admin"];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [auth base64EncodedString]];
[manager.requestSerializer setValue:authValue forHTTPHeaderField:#"Authorization"];
But I struggle to understand how to authenticate with the session security which is bundled in jHipster/spring boot.
First of all, do not use HTTP session authentication for mobile apps.
On the other hand, Oauth2 or JWT works fine with mobile apps. The basic idea behind them is to get a token from Jhipster to mobile the token has an expiry time. In that time you can use the token to access any REST API of Jhipster to access data.
Below I am showing the code snippet of how I was using the Jhipster rest API in my angularjs based ionic app. I hope it gives the idea of what you need to do.
uncomment cors in application.yml inside jhipster
cors: #By default CORS are not enabled. Uncomment to enable.
allowed-origins: "*"
allowed-methods: GET, PUT, POST, DELETE, OPTIONS
allowed-headers: "*"
exposed-headers:
allow-credentials: true
max-age: 1800
To access REST API with Oauth2 authentication in ionic you must first get the token in the ionic app by
$http({
method: "post",
url: "http://192.168.0.4:8085/[Your app name]/oauth/token",
data: "username=admin&password=admin&grant_type=password&scope=read write&client_secret=my-secret-token-to-change-in-production&client_id=auth2Sconnectapp",
withCredentials: true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'Authorization': 'Basic ' + 'YXV0aDJTY29ubmVjdGFwcDpteS1zZWNyZXQtdG9rZW4tdG8tY2hhbmdlLWluLXByb2R1Y3Rpb24='
}
})
.success(function(data) {
alert("success: " + data);
})
.error(function(data, status) {
alert("ERROR: " + data);
});
Here "YXV0aDJTY29ubmVjdGFwcDpteS1zZWNyZXQtdG9rZW4tdG8tY2hhbmdlLWluLXByb2R1Y3Rpb24=" is equal to (clientId + ":" + clientSecret)--all base64-encoded
The above $http if successful will give you this JSON which contains token and it's expiry time
{
"access_token": "2ce14f67-e91b-411e-89fa-8169e11a1c04",
"token_type": "bearer",
"refresh_token": "37baee3c-f4fe-4340-8997-8d7849821d00",
"expires_in": 525,
"scope": "read write"
}
Take notice of "access_token" and "token_type" if you want to access any API this is what you have to use. We send the token with API to access data until the token expires then we either refresh it or access for a new one.
For example
$http({
method: "get",
url: "http://192.168.0.4:8085/auth-2-sconnect/api/countries",
withCredentials: true,
headers: {
'Authorization':' [token_type] + [space] + [access_token] '
}
})
.success(function(data) {
alert("success: " + data);
})
.error(function(data, status) {
alert("ERROR: " + data);
});
Here a summarisation of how I implemented the solution. It’s real swift code, but please take it as pseudocode, as it might be incorrect.
make a call to whatever method you need to call, passing in such method a callback (block, or equivalent) for the success and one for the failure
func action(
URLString:String,
method:Method,
encoding:Encoding = .JSON,
parameters:[String : AnyObject]?,
success:(statusCode:Int, responseObject:AnyObject)->Void,
failure:(statusCode:Int, error:NSError)->Void
)
Inside the method es. /events you handle a particular case of failure, which is when the status code is 401.
if(r!.statusCode==ResponseCodes.HTTP_UNAUTHORIZED.rawValue){
loginAndAction(URLString, method: method, encoding: encoding, parameters: parameters, success: success, failure: failure)
}else{
failure(statusCode: response.response!.statusCode, error:response.result.error!)
}
In this particular case, instead of returning back the result and calling the failure callback, you call a login() method which, after the necessary parameters, accept the original success() callback
func loginAndAction(
URLString:String,
method:Method,
encoding: Encoding,
parameters:[String:AnyObject]?,
success:(statusCode:Int, responseObject:AnyObject)->Void,
failure:(statusCode:Int, error:NSError)->Void
)->Void
if the authentication succeeds
var d:[String:AnyObject] = response.result.value as! [String:AnyObject]
self.authToken = d["access_token"] as! String
action(URLString, method: method,encoding:encoding, parameters: parameters, success: success, failure: failure)
at this point the method action could use a proper working token.
This should happen only once a day (based on the token expiration), and it is a mechanism appliable to the oauth2 refresh_token call.