Does anyone know how to apply dependencies on cloudflare worker? - cloudflare

I was trying to create a free service using cloudflare but i need to use googleapis and nodemailer. So I need to add the dependencies.

Here is an example of how to access Google Cloud APIs from under a Cloudfalre Worker script. You would just need to create a Google Cloud service account (IAM) with required permissions and a JSON private key for it.
import { getAuthToken } from "web-auth-library/google";
export default {
fetch(req, env) {
cosnt accessToken = await getAuthToken({
credentials: env.GOOGLE_CLOUD_CREDENTIALS,
// TODO: List the required GCP scopes here
scope: "https://www.googleapis.com/auth/cloud-platform",
});
// Access any of the Google Cloud REST APIs using that token
const url = `https://cloudresourcemanager.googleapis.com/v1/projects`;
const headers = new Headers({ authorization: `Bearer ${accessToken}` });
const res = await fetch(url, { headers });
const data = await res.json();
// ...
}
}
References
https://github.com/kriasoft/web-auth-library — OAuth 2.0 library for Cloudflare Workers
https://github.com/kriasoft/cloudflare-starter-kit — Cloudflare Workers Starter Kit

Related

Access request body in ServerMiddleware in NUXT

Im building a simple interface to SeaTable. For security reasons, I'm not storing the DB and user keys in the code but instead set up a very lightweight API in NUXT using Server Middle wear. All is working as expected except for my login API endpoint.. I need to capture req.data but it's not available. All examples I have seen add body-phraser and Express. I don't wanna use express as I want to keep this as light as possible.
import fetch from 'node-fetch';
export default {
path: 'api/auth/login',
handler: async (req, res) => {
let requestOptions = {
method: "POST",
headers: {
"username": usr,
"password": psw
}
}
const url = 'https://MY_URL.com/api2/auth-token/'
const request = await fetch(url, requestOptions)
const data = await request.json()
res.end( JSON.stringify(data) )
}
}
I suppose since this call does not contain any keys i could just make the call on the front end capture the user token and send it to the backend to be stored. Id prefer not to expose even the URL to my seatable instance.

OctoKit with Auth0 (Github Login) in NextJS

I am building a Next JS app that has Github Login through Auth0 and uses the Octokit to fetch user info / repos.
In order to get the IDP I had to setup a management api in auth0. https://community.auth0.com/t/can-i-get-the-github-access-token/47237 which I have setup in my NodeJs server to hide the management api token as : GET /getaccesstoken endpoint
On the client side : /chooserepo page, I have the following code :
const chooserepo = (props) => {
const octokit = new Octokit({
auth: props.accessToken,
});
async function run() {
const res = await octokit.request("GET /user");
console.log("authenticated as ", res.data);
}
run();
And
export const getServerSideProps = withPageAuthRequired({
async getServerSideProps({ req, params }) {
let { user } = getSession(req);
console.log("user from get session ", user);
let url = "http://localhost:4000/getaccesstoken/" + user.sub;
let data = await fetch(url);
let resData = await data.text();
return {
props: { accessToken: resData }, // will be passed to the page component as props
};
},
});
However, I keep getting Bad credentials error. If I directly put the access token in the Octokit it seems to work well, but doesn't work when it's fetching the access token from the server.
It seems like Octokit instance is created before server side props are sent. How do I fix it ?
I figured out the error by comparing the difference between the request headers when hardcoding and fetching access token from server. Turns out quotes and backslashes need to be replaced (and aren't visible when just console logging)

K6 - Authentication - Get Auth Token

I have a mocha javascript file in which I have require function to login to the application in headless browser mode, login using the crendentials and return the jwt authentication.
I want to call this script through K6. But as I understand, calling node module java script from K6 is not possible?
Is there an alternative to this?
I have also just started implementing k6 and had same step to do ;)
Here is how I have done it.
you need to know how to authenticate to the API you want to use. I assume we have it, as you wrote you want to use node modules.
second, use appropriate method to communicate with API
next, catch token and append it to next requests headers
finally, test API with requests you want
I found code snippets on web page with k6 samples for APIs.
I have shorten a bit, sample code and end up with:
import {
describe
} from 'https://jslib.k6.io/functional/0.0.3/index.js';
import {
Httpx,
Request,
Get,
Post
} from 'https://jslib.k6.io/httpx/0.0.2/index.js';
import {
randomIntBetween,
randomItem
} from "https://jslib.k6.io/k6-utils/1.1.0/index.js";
export let options = {
thresholds: {
checks: [{
threshold: 'rate == 1.00',
abortOnFail: true
}],
},
vus: 2,
iterations: 2
};
//defining auth credentials
const CLIENT_ID = 'CLIENT_ID';
const CLIENT_SECRET = 'CLIENT_SECRET';
let session = new Httpx({
baseURL: 'https://url.to.api.com'
});
export default function testSuite() {
describe(`01. Authenticate the client for next operations`, (t) => {
let resp = session.post(`/path/to/auth/method`, {
//this sections relays on your api requirements, in short what is mandatory to be authenticated
grant_type: GRANT_TYPE,
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
});
//printing out response body/status/access_token - for debug
// console.log(resp.body);
// console.log(resp.status);
// console.log(resp.json('access_token'));
//defining checks
t.expect(resp.status).as("Auth status").toBeBetween(200, 204)
.and(resp).toHaveValidJson()
.and(resp.json('access_token')).as("Auth token").toBeTruthy();
let authToken = resp.json('access_token');
// set the authorization header on the session for the subsequent requests.
session.addHeader('Authorization', `Bearer ${authToken}`);
})
describe('02. use other API method, but with authentication token in header ', (t) => {
let response = session.post(`/path/to/some/other/post/method`, {
"Cache-Control": "no-cache",
"SomeRequieredAttribute":"AttributeValue"
});
t.expect(response.status).as("response status").toBeBetween(200, 204)
.and(response).toHaveValidJson();
})
}

AWS-amplify Including the cognito Authorization header in the request

I have create an AWS mobile hub project including the Cognito and Cloud logic. In my API gateway, I set the Cognito user pool for the Authorizers. I use React native as my client side app. How can I add the Authorization header to my API request.
const request = {
body: {
attr: value
}
};
API.post(apiName, path, request)
.then(response => {
// Add your code here
console.log(response);
})
.catch(error => {
console.log(error);
});
};
By default, the API module of aws-amplify will attempt to sig4 sign requests. This is great if your Authorizer type is AWS_IAM.
This is obviously not what you want when using a Cognito User Pool Authorizer. In this case, you need to pass the id_token in the Authorization header, instead of a sig4 signature.
Today, you can indeed pass an Authorization header to amplify, and it will no longer overwrite it with the sig4 signature.
In your case, you just need to add the headers object to your request object. For example:
async function callApi() {
// You may have saved off the JWT somewhere when the user logged in.
// If not, get the token from aws-amplify:
const user = await Auth.currentAuthenticatedUser();
const token = user.signInUserSession.idToken.jwtToken;
const request = {
body: {
attr: "value"
},
headers: {
Authorization: token
}
};
var response = await API.post(apiName, path, request)
.catch(error => {
console.log(error);
});
document.getElementById('output-container').innerHTML = JSON.stringify(response);
}
Tested using aws-amplify 0.4.1.

Unable to Authorize users using Implicit / Authorization flow in google actions

I am trying to link to the account :
Here is my google cloud function
var AuthHandler = function() {
this.googleSignIn = googleSignIn;
this.googleSignInCallback = googleSignInCallback;
}
function googleSignIn(req, res, next) {
passport = req._passport.instance;
passport.authenticate('google',{scope: 'https://www.googleapis.com/auth/userinfo.email',
state:"google",response_type:"token"},
function(err, user, info) {
console.log(user);
})(req,res,next);
};
function googleSignInCallback(req, res, next) {
passport = req._passport.instance;
passport.authenticate('google',function(err, user, info) {
if(err) {
return next(err);
}
if(!user) {
return res.redirect('http://localhost:8000');
}
console.log(user._json.token);
// /res.redirect('/');
res.redirect('https://oauth-redirect.googleusercontent.com/r/xxxxxx#access_token=' + user._json.token + '&token_type=bearer&state=google')
})(req,res,next);
};
module.exports = AuthHandler;
In google Action Console :
I have created the implicit flow and gave my authorisation url as follows:
https://[region]-[projectid].cloudfunctions.net/[functionname]/auth/google
Error :
this is the browser Url
https://assistant.google.com/services/auth/handoffs/auth/complete?state=xxxx&code=xxxxxx
on which the following error is displayed
The parameter "state" must be set in the query string.
Update 1
Before starting this implementation , i have followed this Solution to create the Authentication.
Problems in this Approach :
1.As stated in the Documentation it is not redirecting to google.com and i'm unable to access the token using the APIAI SDK in javascript. but still i can see the Access token in emulator . for better understanding adding images
Here is my simulator O/P
{
"response": {
"debug": {
"agentToAssistantDebug": {
"assistantToAgentDebug": {
"assistantToAgentJson": "{"accessToken\":\"xxxxxx\""
}
},
"errors": []
}
Update 2 :
So i have started creating with implicit flow and here is my complete repo
After battling with it i have achieved it , as there is no proper articles about creation of own Oauth Server that implements the Google Action , this might helpful for future users.
Authorization Endpoint
app.get('/authorise', function(req, res) {
req.headers.Authorization = 'Bearer xxxxxxxxxxx';
// with your own mechanism after successful
//login you need to create a access token for the generation of
//authorization code and append it to this header;
var request = new Request(req);
var response = new Response(res);
oauth.authorize(request, response).then(function(success) {
// https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID?
//code=AUTHORIZATION_CODE&state=STATE_STRING
var toredirect = success.redirectUri +"?code="+success.code
+"&state="+request.query.state ;
return res.redirect(toredirect);
}).catch(function(err){
res.status(err.code || 500).json(err)
}) });
Token Endpoint :
app.all('/oauth/token', function(req,res,next){
var request = new Request(req);
var response = new Response(res);
oauth
.token(request,response)
.then(function(token) {
// Todo: remove unnecessary values in response
return res.json(token)
}).catch(function(err){
return res.status(500).json(err)
})
});
After creation of this endpoints publish to the Google Cloud functions . I have used MYSQL as the DB using SEQUELIZE and Oauth-Server , if anyone need those models , will share it through repo .
With this you can able to link account using your own Server which implements
Auth tokens and Access Tokens
I think the problem is that the URL on this line isn't sending the parameters as query parameters, they're sending them as part of the anchor:
res.redirect('https://oauth-redirect.googleusercontent.com/r/xxxxxx#access_token=' + user._json.token + '&token_type=bearer&state=google')
You should replace the # with a ?, as illustrated here:
res.redirect('https://oauth-redirect.googleusercontent.com/r/xxxxxx?access_token=' + user._json.token + '&token_type=bearer&state=google')