I need to be able to add the following button to Swagger's UI interface so that the testers can add the "Bearer token" header and test the apis.
My swagger's option definition is:
module.exports = {
definition: {
openapi: "3.0.3",
info: {
title: "APIs",
version: "1.0.0",
},
servers: [
{
url: `http://localhost:${process.env.PORT}`
}
],
securityDefinitions: {
bearerAuth: {
type: 'apiKey',
name: 'Authorization',
scheme: 'bearer',
in: 'header',
},
}
},
apis: ["./routes/*.js", "app.js"],
};
and my endpoint is as follows:
/**
* #swagger
* /api/users/test:
* post:
* security:
* - Bearer: []
* summary: test authorization
* tags: [User]
* description: use to test authorization JWT
* responses:
* '200':
* description: success
* '500':
* description: Internal server error
*/
router.post('/test', verifyJWT(), async (req, res) => {
res.send('hi');
})
Are you using OAS v3? You have errors in your declarations, for example securityDefinitions is now called securitySchemes and it is inside components.
Check https://swagger.io/docs/specification/authentication/
When you fix your schema, then you add a security property to your path to protect it with a security schema so that you'll get the green Authorize button.
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
paths:
/api/users/test:
post:
security:
- BearerAuth: []
Related
I am developing a REST API with Node.Js. my technology stack is AWS Lambda, API Gateway and RDS (MySQL). Below is my code
roles.js
const mysql = require('mysql');
const con = mysql.createConnection({
host : "*****.rds.amazonaws.com",
user : "*****",
password : "*****",
port : 3306,
database : "******"
});
exports.lambdaHandler = (event, context, callback) => {
// allows for using callbacks as finish/error-handlers
context.callbackWaitsForEmptyEventLoop = false;
const sql = "select * from role";
con.query(sql, function (err, result) {
if (err) throw err;
var response = {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": JSON.stringify(result),
"isBase64Encoded": false
};
callback(null, response)
});
};
exports.selectRoleByIDHandler = (event, context, callback) => {
const { id } = event.queryStringParameters;
console.log("id", id);
// allows for using callbacks as finish/error-handlers
context.callbackWaitsForEmptyEventLoop = false;
const sql = "select * from role where idRole = "+id;
con.query(sql, function (err, result) {
if (err) throw err;
var response = {
"statusCode": 200,
"headers": {
"Content-Type": "application/json"
},
"body": JSON.stringify(result),
"isBase64Encoded": false
};
callback(null, response)
});
};
Below is my template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
node2
Sample SAM Template for node2
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 100
VpcConfig:
SecurityGroupIds:
- sg-sdsdsdsd
SubnetIds:
- subnet-ssdsds
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: app.lambdaHandler
Runtime: nodejs14.x
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /hello
Method: get
Role: !GetAtt LambdaRole.Arn
RoleFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: roles.lambdaHandler
Runtime: nodejs14.x
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /roles
Method: get
Role: !GetAtt LambdaRole.Arn
SelectRolesByIDFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: hello-world/
Handler: roles.selectRoleByIDHandler
Runtime: nodejs14.x
Events:
HelloWorld:
Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /selectRoleByIDHandler
Method: get
Role: !GetAtt LambdaRole.Arn
LambdaRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- 'sts:AssumeRole'
Path: /
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: root
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- ec2:DescribeNetworkInterfaces
- ec2:CreateNetworkInterface
- ec2:DeleteNetworkInterface
- ec2:DescribeInstances
- ec2:AttachNetworkInterface
Resource: '*'
When I try to execute the sam local invoke, i get the following error
Error: You must provide a function logical ID when there are more than one functions in your template. Possible options in your template: ['HelloWorldFunction', 'RoleFunction', 'SelectRolesByIDFunction']
Now, I have 2 questions.
How to solve this issue?
Is it a bad practice to have more than one function in a single file in AWS Lambda?
Looks like you are trying to build Lambda functions via the AWS SDK for Javascipt. Have you looked at the AWS examples in the AWS SDK for JavaScript V3 DEV Guide. There are end to end instructions on how to build Lambda function using the JS API that can help you.
See this topic and the child topics in the TOC:
Cross-service examples for the AWS SDK for JavaScript
I found the issue, I had to invoke this as sam local invoke HelloWorldFunction . The HelloWorldFunction is the function name I need to deploy.
I using swagger and I add auth today. But even if I write any letter like " a " or "abc" or what its still entering. How can I check is it true token for use swagger? My code:
const options = {
definition: {
openapi: "3.0.0",
info: {
title: "İlaç Takip Sistemi API",
version: "2.0.0",
description: "ITS API Swagger",
},
servers: [
{
url: "http://localhost:3100",
},
],
components: {
securitySchemes: {
bearerAuth: {
type: "apiKey",
name: "x-auth-token",
scheme: "bearer",
in: "header",
},
},
},
security: [
{
bearerAuth: [],
},
],
},
apis: ["./app/routes.js"],
};
const specs = swaggerJsDoc(options);
app.use("/swagger", swaggerUI.serve, swaggerUI.setup(specs));
This is how i check Token :
jwt.verify(req.token, process.env.SECRETKEY, (err, authData) => {
if (err) {
res.sendStatus(401);
} else {
res.json(authData);
}
});
When i write my token to swagger then do my works in there but when i try from swagger its saying Unauthorized even my token is true and working while i trying in postman.
Change your security scheme as follows:
bearerAuth: {
type: "http",
scheme: "bearer",
},
This way the "Bearer" prefix will be added automatically to the tokens you enter in Swagger UI.
When using type: "apiKey" for Bearer authentication, you would have to include the "Bearer " prefix in the token value, that is, enter the token as Bearer abc123 in Swagger UI.
I need to do a new api in order to send an email with sendgrid. I followed the official doc and other examples so I did:
config/plugins
module.exports = ({ env }) => ({
email: {
provider: 'sendgrid',
providerOptions: {
apiKey: env('SENDGRID_API_KEY'),
},
settings: {
defaultFrom: 'juliasedefdjian#strapi.io',
defaultReplyTo: 'juliasedefdjian#strapi.io',
},
},
});
then I did a new folder named email in api folder
api/email/config/routes.json
{
"routes": [
{
"method": "POST",
"path": "/email",
"handler": "email.index",
"config": {
"policies": []
}
}
]
}
finally under api/email/controllers/email.js
const { default: createStrapi } = require('strapi');
module.exports = {
index: async (ctx) => {
//build email with data from ctx.request.body
await createStrapi.plugins['email'].services.email.send({
to: 'email#email.com',
from: 'email#email.com',
replyTo: 'email#email.com',
subject: 'test',
text: 'test',
});
ctx.send('Email sent!');
},
};
The real problem is that /email api returns me a 403 even if I did this from the dashboard:
I have done many APIs with strapi but I have never sent emails with it.
Is there a way to add permissions from the code? I have to say that if I use GET method it works, but I need to do it with a POST method, which doesn't. Did I miss something?
I currently have a loopback project setup, and I am trying to receive webhooks from stripe.
My current Remote method looks like the following:-
Stripeconnect.stripeWebhook = function(msg, cb) {
cb(null, msg);
};
Stripeconnect.remoteMethod(
'stripeWebhook', {
description: 'This will insert the description',
http: {
path: '/stripeWebhook',
verb: 'get'
},
accepts:
{arg: 'msg', type: 'any'},
returns: {
arg: 'status',
type: 'any'
}
}
)
But in the response I receive from Stripe is:-
undefined [Function: callback]
I am unable to find any documentation online regarding Loopback and Stripe webhooks.
Would anybody be able to help, or point me in the right direction?
I have setup Stripe to point at this endpoint of the API.
Thanks in advance. If you need anymore info please let me know.
Ok so I was able to get this working by getting the response from the body:-
/**
* Receiving Webhook
* #desc Webhook EP
* #param {data} Object from Stripe.
* #return {response} response code
*/
Stripeconnect.stripeWebhook = function(request, cb) {
console.log(request.type, request.data);
};
Stripeconnect.remoteMethod(
'stripeWebhook', {
accepts: { arg: 'data', type: 'object', http: { source: 'body' } },
returns: [
{arg: 'response', type: 'any', root: true }
]
});
Which you can see from:-
accepts: { arg: 'data', type: 'object', http: { source: 'body' } },
Hopefully this helps anybody else who is having this or a similar issue.
I’m using mean.js to let registered users access content. It’s sort of working. I can change isAllowed to !isAllowed to let people see the content. The problem is that content is not authorized when the user logs in. The articles example works fine. But when I create my own section, logged in users can’t access pages!
So basically if I log in, I get message: 'User is not authorized' if I try going to localhost:3000/requestoffwork
If I log in and change isAllowed to !isAllowed, I can access it
'use strict';
/**
* Module dependencies.
*/
var acl = require('acl');
// Using the memory backend
acl = new acl(new acl.memoryBackend());
/**
* Invoke Articles Permissions
*/
exports.invokeRolesPolicies = function () {
acl.allow([{
roles: ['admin'],
allows: [{
resources: '/api/articles',
permissions: '*'
}, {
resources: '/api/articles/:articleId',
permissions: '*'
}]
}, {
roles: ['user'],
allows: [{
resources: '/requestoffwork',
permissions: '*'
}, {
resources: '/api/articles/:articleId',
permissions: ['get']
}]
}, {
roles: ['guest'],
allows: [{
resources: '/api/articles',
permissions: ['get']
}, {
resources: '/api/articles/:articleId',
permissions: ['get']
}]
}]);
};
/**
* Check If Articles Policy Allows
*/
exports.isAllowed = function (req, res, next) {
var roles = (req.user) ? req.user.roles : ['guest'];
// If an article is being processed and the current user created it then allow any manipulation
if (req.article && req.user && req.article.user.id === req.user.id) {
return next();
}
// Check for user roles
acl.areAnyRolesAllowed(roles, req.route.path, req.method.toLowerCase(), function (err, isAllowed) {
if (err) {
// An authorization error occurred.
return res.status(500).send('Unexpected authorization error');
} else {
if (isAllowed) {
// Access granted! Invoke next middleware
return next();
} else {
return res.status(403).json({
message: 'User is not authorized'
});
}
}
});
};
This is the route
app.route('/requestoffwork').all(managementPolicy.isAllowed)
.get(management.list)
.post(management.submit);
And here's the data for the user
{"_id":"5788fe46587a1c0b07a04078","displayName":"","provider":"local","__v":0,"created":"2016-07-15T15:16:22.625Z","roles":["user"],"profileImageURL":"modules/users/client/img/profile/default.png","email":"email#gmail.com","lastName":"","firstName":”"}
Did you add the permissions to the client side routes ass well ?
In modules/youModule/client/config/youModule.client.routes.js add this:
function routeConfig($stateProvider) {
$stateProvider
.state('yourState', {
abstract: true,
url: '/requestoffwork',
template: '<ui-view/>',
data: {
roles: ['user'], //here you must specify the roles as well
pageTitle: 'requestoffwork'
}
})
}
Hope this helps.