Route spoofing failing with space

#1

Hi Adonites,

I have this form action:

<form method=“POST” action="{{ ‘/students/’ + student.id }} ‘?_method=PUT’">

… which I think should be caught by this route:

Route.put(‘students/:id’, ‘StudentController.update’);

… but instead i’m receiving this error:

E_ROUTE_NOT_FOUND: Route not found PUT’ /students/3%20’

3 is the correct ID. The space at the end is suspicious to me - maybe that’s what’s throwing it off. Is method spoofing spoofed, or am I doing it wrong?

Marty

0 Likes

#2

Maybe you wanna do the following

1.- Write a name for your route


Route.post(‘students/:id’, ‘StudentController.update’).as('students.update')

2.- Now on your HTML form, use the route helper to invoke it


<form method=“POST” action="{{ route('users.update', {id: variableName.id}) }}">

0 Likes

#3

Thanks for looking at that ShadowPaz. The reason I’m using route spoofing to get a PUT on my update is I’m already using POST on my create.

By the way, I got rid of the space by taking it out of form action:

<form method=“POST” action="{{ ‘/students/’ + student.id }}’?_method=PUT’">

… but that didn’t turn out to be the problem. It looks like the Route.put just isn’t catching it.
I think I can use POST with or without an id, to distinguish the two.

0 Likes

#4

Can you share config/app.js file contents?

0 Likes

#5

‘use strict’

/** @type {import(’@adonisjs/framework/src/Env’)} */
const Env = use(‘Env’)

module.exports = {

/*
|--------------------------------------------------------------------------

Application Name
This value is the name of your application and can used when you
need to place the application’s name in a email, view or
other location.

*/

name: Env.get(‘APP_NAME’, ‘AdonisJs’),

/*
|--------------------------------------------------------------------------

App Key
App key is a randomly generated 16 or 32 characters long string required
to encrypted cookies, sessions and other sensitive data.

*/
appKey: Env.getOrFail(‘APP_KEY’),

http: {
/*
|--------------------------------------------------------------------------
| Allow Method Spoofing
|--------------------------------------------------------------------------
|
| Method spoofing allows to make requests by spoofing the http verb.
| Which means you can make a GET request but instruct the server to
| treat as a POST or PUT request. If you want this feature, set the
| below value to true.
|
*/
allowMethodSpoofing: true,

/*
|--------------------------------------------------------------------------
| Trust Proxy
|--------------------------------------------------------------------------
|
| Trust proxy defines whether X-Forwaded-* headers should be trusted or not.
| When your application is behind a proxy server like nginx, these values
| are set automatically and should be trusted. Apart from setting it
| to true or false Adonis supports handful or ways to allow proxy
| values. Read documentation for that.
|
*/
trustProxy: false,

/*
|--------------------------------------------------------------------------
| Subdomains
|--------------------------------------------------------------------------
|
| Offset to be used for returning subdomains for a given request.For
| majority of applications it will be 2, until you have nested
| sudomains.
| cheatsheet.adonisjs.com      - offset - 2
| virk.cheatsheet.adonisjs.com - offset - 3
|
*/
subdomainOffset: 2,

/*
|--------------------------------------------------------------------------
| JSONP Callback
|--------------------------------------------------------------------------
|
| Default jsonp callback to be used when callback query string is missing
| in request url.
|
*/
jsonpCallback: 'callback',


/*
|--------------------------------------------------------------------------
| Etag
|--------------------------------------------------------------------------
|
| Set etag on all HTTP response. In order to disable for selected routes,
| you can call the `response.send` with an options object as follows.
|
| response.send('Hello', { ignoreEtag: true })
|
*/
etag: false

},

views: {
/*
|--------------------------------------------------------------------------
| Cache Views
|--------------------------------------------------------------------------
|
| Define whether or not to cache the compiled view. Set it to true in
| production to optimize view loading time.
|
*/
cache: Env.get(‘CACHE_VIEWS’, true)
},

static: {
/*
|--------------------------------------------------------------------------
| Dot Files
|--------------------------------------------------------------------------
|
| Define how to treat dot files when trying to server static resources.
| By default it is set to ignore, which will pretend that dotfiles
| does not exists.
|
| Can be one of the following
| ignore, deny, allow
|
*/
dotfiles: ‘ignore’,

/*
|--------------------------------------------------------------------------
| ETag
|--------------------------------------------------------------------------
|
| Enable or disable etag generation
|
*/
etag: true,

/*
|--------------------------------------------------------------------------
| Extensions
|--------------------------------------------------------------------------
|
| Set file extension fallbacks. When set, if a file is not found, the given
| extensions will be added to the file name and search for. The first
| that exists will be served. Example: ['html', 'htm'].
|
*/
extensions: false

},

locales: {
/*
|--------------------------------------------------------------------------
| Loader
|--------------------------------------------------------------------------
|
| The loader to be used for fetching and updating locales. Below is the
| list of available options.
|
| file, database
|
*/
loader: ‘file’,

/*
|--------------------------------------------------------------------------
| Default Locale
|--------------------------------------------------------------------------
|
| Default locale to be used by Antl provider. You can always switch drivers
| in runtime or use the official Antl middleware to detect the driver
| based on HTTP headers/query string.
|
*/
locale: 'en'

},

logger: {
/*
|--------------------------------------------------------------------------
| Transport
|--------------------------------------------------------------------------
|
| Transport to be used for logging messages. You can have multiple
| transports using same driver.
|
| Available drivers are: file and console.
|
*/
transport: ‘console’,

/*
|--------------------------------------------------------------------------
| Console Transport
|--------------------------------------------------------------------------
|
| Using `console` driver for logging. This driver writes to `stdout`
| and `stderr`
|
*/
console: {
  driver: 'console',
  name: 'adonis-app',
  level: 'info'
},

/*
|--------------------------------------------------------------------------
| File Transport
|--------------------------------------------------------------------------
|
| File transport uses file driver and writes log messages for a given
| file inside `tmp` directory for your app.
|
| For a different directory, set an absolute path for the filename.
|
*/
file: {
  driver: 'file',
  name: 'adonis-app',
  filename: 'adonis.log',
  level: 'info'
}

},

/*
|--------------------------------------------------------------------------

Generic Cookie Options
The following cookie options are generic settings used by AdonisJs to create
cookies. However, some parts of the application like sessions can have
seperate settings for cookies inside config/session.js.

*/
cookie: {
httpOnly: true,
sameSite: false,
path: ‘/’,
maxAge: 7200
}
}

0 Likes

#6

I’ve worked around this, for now, but using a POST without ID for my store and POST with ID for my update. It seems like the problem is Route.put not catching the PUT.

Kudos to the Adonis developers - it is a very cool framework! If this is the worst defect I bump into I’ll be ecstatic!

0 Likes