gpt4 book ai didi

javascript - Adonis.js RESTFUL API 解决方法

转载 作者:行者123 更新时间:2023-11-30 14:59:22 26 4
gpt4 key购买 nike

我最近开始在 adonisjs 框架上开发一个应用程序。我可以选择使用 expressjs,但我更喜欢 adonisjs,因为我喜欢它的结构方式(主要是 laravel 风格)。

我目前正在尝试构建一个 RESTFUL API,但无法弄清楚基本的路由/中间件/apiController(我的自定义 Controller 来处理所有 api 请求)场景。

这是我到目前为止所做的:

路由.js

Route.post('api/v1/login', 'ApiController.login')
Route.post('api/v1/register', 'ApiController.register')

// API Routes
Route.group('api', function() {

Route.get('users', 'ApiController.getUsers')

}).prefix('/api/v1').middlewares(['auth:api'])

ApiController.js

'use strict'

const User = use('App/Model/User')
const Validator = use('Validator')

const FAIL = 0
const SUCCESS = 1

class ApiController {

* login (request, response) {

let jsonResponse = {}

const email = request.input('email')
const password = request.input('password')

// validate form input
const rules = {
email: 'required|email',
password: 'required'
}

const messages = {
'email.required': 'Email field is required.',
'password.required': 'Password field is required.'
}

const validation = yield Validator.validateAll(request.all(), rules, messages)

if (validation.fails()) {

jsonResponse.status = FAIL
jsonResponse.response = {}
jsonResponse.response.message = validation.messages()[0].message

} else {

try {

yield request.auth.attempt(email, password)

const user = yield User.findBy('email', email)

const token = yield request.auth.generate(user)

jsonResponse.status = SUCCESS
jsonResponse.response = {}
jsonResponse.response.message = "Logged In Successfully"
jsonResponse.response.user = user
jsonResponse.response.token = token

} catch (e) {

jsonResponse.status = FAIL
jsonResponse.response = {}
jsonResponse.response.message = e.message

}

}

return response.json(jsonResponse)

}

}

module.exports = ApiController

配置/auth.js

'use strict'

const Config = use('Config')

module.exports = {

/*
|--------------------------------------------------------------------------
| Authenticator
|--------------------------------------------------------------------------
|
| Authenticator is a combination of HTTP Authentication scheme and the
| serializer to be used for retrieving users. Below is the default
| authenticator to be used for every request.
|
| Available Schemes - basic, session, jwt, api
| Available Serializers - Lucid, Database
|
*/
authenticator: 'session',

/*
|--------------------------------------------------------------------------
| Session Authenticator
|--------------------------------------------------------------------------
|
| Session authenticator will make use of sessions to maintain the login
| state for a given user.
|
*/
session: {
serializer: 'Lucid',
model: 'App/Model/User',
scheme: 'session',
uid: 'email',
password: 'password'
},

/*
|--------------------------------------------------------------------------
| Basic Auth Authenticator
|--------------------------------------------------------------------------
|
| Basic Authentication works on Http Basic auth header.
|
*/
basic: {
serializer: 'Lucid',
model: 'App/Model/User',
scheme: 'basic',
uid: 'email',
password: 'password'
},

/*
|--------------------------------------------------------------------------
| JWT Authenticator
|--------------------------------------------------------------------------
|
| Jwt authentication works with a payload sent with every request under
| Http Authorization header.
|
*/
jwt: {
serializer: 'Lucid',
model: 'App/Model/User',
scheme: 'jwt',
uid: 'email',
password: 'password',
secret: Config.get('app.appKey')
},

/*
|--------------------------------------------------------------------------
| API Authenticator
|--------------------------------------------------------------------------
|
| Api authenticator authenticates are requests based on Authorization
| header.
|
| Make sure to define relationships on User and Token model as defined
| in documentation
|
*/
api: {
serializer: 'Lucid',
model: 'App/Model/Token',
scheme: 'api'
}

}

配置/shield.js

'use strict'

module.exports = {
/*
|--------------------------------------------------------------------------
| Content Security Policy
|--------------------------------------------------------------------------
|
| Content security policy filters out the origins not allowed to execute
| and load resources like scripts, styles and fonts. There are wide
| variety of options to choose from.
| @examples
| directives: {
| defaultSrc: ['self', '@nonce', 'cdnjs.cloudflare.com']
| }
*/
csp: {
directives: {
},
reportOnly: false,
setAllHeaders: false,
disableAndroid: true
},

/*
|--------------------------------------------------------------------------
| X-XSS-Protection
|--------------------------------------------------------------------------
|
| X-XSS Protection saves from applications from XSS attacks. It is adopted
| by IE and later followed by some other browsers.
|
*/
xss: {
enabled: true,
enableOnOldIE: false
},

/*
|--------------------------------------------------------------------------
| Iframe Options
|--------------------------------------------------------------------------
|
| xframe defines whether or not your website can be embedded inside an
| iframe. Choose from one of the following options.
| @available options
| DENY, SAMEORIGIN, ALLOW-FROM http://example.com
*/
xframe: 'DENY',

/*
|--------------------------------------------------------------------------
| No Sniff
|--------------------------------------------------------------------------
|
| Browsers have a habit of sniffing content-type of a response. Which means
| files with .txt extension containing Javascript code will be executed as
| Javascript. You can disable this behavior by setting nosniff to false.
|
*/
nosniff: true,

/*
|--------------------------------------------------------------------------
| No Open
|--------------------------------------------------------------------------
|
| IE users can execute webpages in the context of your website, which is
| a serious security risk. Below options will manage this for you.
|
*/
noopen: true,

/*
|--------------------------------------------------------------------------
| CSRF Protection
|--------------------------------------------------------------------------
|
| CSRF Protection adds another layer of security by making sure, actionable
| routes does have a valid token to execute an action.
|
*/
csrf: {
enable: true,
methods: ['POST', 'PUT', 'DELETE'],
filterUris: ['/api/v1/login', '/api/v1/register'],
compareHostAndOrigin: true
}

}

现在,当我点击登录网络服务时(使用 postman )。它会验证用户,但会在 const token = request.auth.generate(user) 处抛出异常并提示 request.auth.generate is not a function

我不知道这是怎么回事。请帮忙。

谢谢

最佳答案

您需要生成一个 JWT token (当用户调用登录 api 调用时)并将其发回,以便请求登录服务的应用程序可以存储它并使用它来发出 future 的请求(使用“授权” header 和值“不记名 [JWT token 字符串]”)。当应用程序发送另一个请求,即获取业务类别列表(在其 header 中带有 JWT token )时,我们将在 api 中间件中验证该请求。请求通过验证后,我们将处理请求并以 json 格式发回数据。

这是您的 header 的样子:

image

这就是您实际需要在代码中执行的操作:

//路由.JS

// API Routes
Route.post('/api/v1/register', 'ApiController.register')
Route.post('/api/v1/login', 'ApiController.login')

Route.group('api', function() {

Route.get('/business_categories', 'ApiController.business_categories')

}).prefix('/api/v1').middlewares(['api'])

//API.JS(中间件)

'use strict'

class Api {

* handle (request, response, next) {

// here goes your middleware logic
const authenticator = request.auth.authenticator('jwt')
const isLoggedIn = yield authenticator.check()

if (!isLoggedIn) {
return response.json({
status: 0,
response: {
message: 'API Authentication Failed.'
}
})
}

// yield next to pass the request to next middleware or controller
yield next

}

}

module.exports = Api

//APICONTROLLER.JS

'use strict'

// Dependencies
const Env = use('Env')
const Validator = use('Validator')
const Config = use('Config')
const Database = use('Database')
const Helpers = use('Helpers')
const RandomString = use('randomstring')
const Email = use('emailjs')
const View = use('View')

// Models
const User = use('App/Model/User')
const UserProfile = use('App/Model/UserProfile')
const DesignCenter = use('App/Model/DesignCenter')
const Settings = use('App/Model/Setting')

// Properties
const FAIL = 0
const SUCCESS = 1
const SITE_URL = "http://"+Env.get('HOST')+":"+Env.get('PORT')

// Messages
const MSG_API_AUTH_FAILED = 'Api Authentication Failed.'
const MSG_REGISTERED_SUCCESS = 'Registered Successfully.'
const MSG_LOGGED_IN_SUCCESS = 'Logged In Successfully.'
const MSG_LOGGED_IN_CHECK = 'You Are Logged In.'
const MSG_LOGGED_IN_FAIL = 'Invalid Credentials.'
const MSG_FORGOT_PASS_EMAIL_SUCCESS = 'Your password reset email has been sent. Please check your inbox to continue.'

class ApiController {

* register (request, response) {

let jsonResponse = {}

// validate form input
const validation = yield Validator.validateAll(request.all(), Config.get('validation.api.register.rules'), Config.get('validation.api.register.messages'))

// show error messages upon validation fail
if (validation.fails()) {

jsonResponse.status = FAIL
jsonResponse.response = {}
jsonResponse.response.message = validation.messages()[0].message

} else {

// handle card image
let card_image = null

if ( request.file('card_image') ) {

const image = request.file('card_image', {
allowedExtensions: ['jpg', 'png', 'jpeg']
})

if (image.clientSize() > 0) {
const filename = RandomString.generate({length: 30, capitalization: 'lowercase'}) + '.' + image.extension()
yield image.move(Helpers.publicPath(Config.get('constants.user_card_img_upload_path')), filename)

if (!image.moved()) {
jsonResponse.status = FAIL
jsonResponse.response = {}
jsonResponse.response.message = image.errors()
return response.json(jsonResponse)
}

// set value for DB
card_image = filename
}

}

// create user
const user = yield User.create({
username: new Date().getTime(),
email: request.input('email'),
password: request.input('password')
})

// create user profile
const user_profile = yield UserProfile.create({
user_id: user.id,
user_type_id: 3, // designer
first_name: request.input('first_name'),
last_name: request.input('last_name'),
business_name: request.input('business_name'),
business_category_id: request.input('business_category'),
card_image: card_image,
phone: request.input('mobile_no'),
is_active: 1
})

jsonResponse.status = SUCCESS
jsonResponse.response = {}
jsonResponse.response.message = MSG_REGISTERED_SUCCESS
jsonResponse.response.user = {
'id': user.id,
'first_name': user_profile.first_name,
'last_name': user_profile.last_name,
'business_name': user_profile.business_name,
'business_category_id': user_profile.business_category_id,
'card_image': user_profile.card_image == null ? "" : SITE_URL + "/" + Config.get('constants.user_card_img_upload_path') + "/" + user_profile.card_image,
'mobile_no': user_profile.phone
}

}

return response.json(jsonResponse)

}

* login (request, response) {

let jsonResponse = {}

const email = request.input('email')
const password = request.input('password')

// validate form input
const validation = yield Validator.validateAll(request.all(), Config.get('validation.api.login.rules'), Config.get('validation.api.login.messages'))

if (validation.fails()) {

jsonResponse.status = FAIL
jsonResponse.response = {}
jsonResponse.response.message = validation.messages()[0].message

} else {

try {
const jwt = request.auth.authenticator('jwt')
const token = yield jwt.attempt(email, password)
const user = yield User.findBy('email', email)
const user_profile = yield UserProfile.findBy('user_id', user.id)

// check if user type is designer
if ( user_profile.user_type_id == 3 ) {

jsonResponse.status = SUCCESS
jsonResponse.response = {}
jsonResponse.response.message = MSG_LOGGED_IN_SUCCESS

let card_image = null
if (user_profile.card_image) {
card_image = SITE_URL + "/" + Config.get('constants.user_card_img_upload_path') + "/" + user_profile.card_image
}

jsonResponse.response.user = {
'id': user.id,
'first_name': user_profile.first_name,
'last_name': user_profile.last_name,
'business_name': user_profile.business_name,
'business_category_id': user_profile.business_category_id,
'card_image': card_image,
'mobile_no': user_profile.phone
}
jsonResponse.response.token = token

} else {

jsonResponse.status = FAIL
jsonResponse.response = {}
jsonResponse.response.message = MSG_LOGGED_IN_FAIL

}
} catch (e) {
jsonResponse.status = FAIL
jsonResponse.response = {}
jsonResponse.response.message = e.message
}

}

return response.json(jsonResponse)

}

* business_categories (request, response) {

let jsonResponse = {}

try {

jsonResponse.status = SUCCESS
const dbRecords = yield Database.select('id', 'name').from('business_categories')
let records = []

dbRecords.forEach(function(row) {
records.push({
id: row.id,
name: row.name
})
})

jsonResponse.response = records

} catch (e) {

jsonResponse.status = FAIL
jsonResponse.response = {}
jsonResponse.response.message = e.message

}

response.json(jsonResponse)

}

module.exports = ApiController

//配置/AUTH.JS

因为 JWT token 保持有效,除非它们过期或删除(从应用程序中,当强制注销用户时)。我们还可以设置一个有效期,如下所示:

jwt: {
serializer: 'Lucid',
model: 'App/Model/User',
scheme: 'jwt',
uid: 'email',
password: 'password',
secret: Config.get('app.appKey'),
options: {
// Options to be used while generating token
expiresIn: Ms('3m') // 3 months
}
}

//配置/SHIELD.JS

由于大多数 api 服务无法在发送 POST 请求时发送 CSRF token ,您可以在该文件中排除那些不检查 CSRF token 的 api 路径,如下所示:

csrf: {
enable: true,
methods: ['POST', 'PUT', 'DELETE'],
filterUris: [
'/api/v1/login',
'/api/v1/register'
],
compareHostAndOrigin: true
}

希望这有帮助:)

关于javascript - Adonis.js RESTFUL API 解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46764312/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com