When I redirect to another action in the same controller the 'request' is null.
def updateEmployee() {
println "updateEmployee(): request =" + request.JSON
redirect(action: "createEmployee", params: params)
}
def createEmployee() {
def renderStatus = 500;
System.out.println "createEmployee() : request= " + request.JSON;
the updateEmployee prints all the request data, but creteEmployee prints it as null ([:])
How to redirect the 'request' (I mean the POST data ) ?
You cannot redirect POST request. Redirect mean a new GET request, so all previous data from previous request will be lost.
If you need to call another action without actual redirect use forward: http://grails.org/doc/latest/ref/Controllers/forward.html
Related
I am having an issue getting devise_token_auth logout working.
I am working based on these SO:
How to set header and options in axios?
Why am I unable to sign out using devise_token_auth and curl?
This is the devise token auth, destroy method. It does reach this method and stops at a breakpoint.
https://github.com/lynndylanhurley/devise_token_auth/blob/c92258038c05fcc8f6a0374ccce2e63b9f8d5312/app/controllers/devise_token_auth/sessions_controller.rb#L48
def destroy
# remove auth instance variables so that after_action does not run
user = remove_instance_variable(:#resource) if #resource
client = #token.client
#token.clear!
if user && client && user.tokens[client]
user.tokens.delete(client)
user.save!
yield user if block_given?
render_destroy_success
else
render_destroy_error
end
end
#token is set in another method and it doesn't appear to be called. I don't quite get how this method is supposed to clear tokens.
My #token is #<struct DeviseTokenAuth::TokenFactory::Token client=nil, token=nil, token_hash=nil, expiry=nil> and #resource is nil at my break point/top of the method.
Client Request (Vue):
methods: {
headers() {
const config = {
headers: {
"uid": localStorage.getItem("uid"),
"client": localStorage.getItem("client"),
"access-token": localStorage.getItem("access-token")
}
}
return config
},
async handleLogOut() {
// e.preventDefault();
const headers = this.headers()
localStorage.removeItem('access-token')
localStorage.removeItem('uid')
localStorage.removeItem('client')
this.logOut();
let response = await axios.get('api/v1/auth/sign_out', null, headers)
}
}
Routes:
destroy_api_user_session GET /api/v1/auth/sign_out(.:format) api/v1/sessions#destroy
What am I doing wrong?
How is the destroy method working?
Ok, I missed this before_action method:
https://github.com/lynndylanhurley/devise_token_auth/blob/c92258038c05fcc8f6a0374ccce2e63b9f8d5312/app/controllers/devise_token_auth/concerns/set_user_by_token.rb#L26
This is where it takes your headers, checks them and sets instance variables.
By finding this I realized I was not sending the headers that I thought I was sending. I changed my http request it works fine.
axios.get('api/v1/auth/sign_out', headers)
Side Note:
The logout action by default in devise is delete but this can be modified:
config.sign_out_via = :get
I am getting '405 method not allowed' error when I try to send a post request using AngularJS http.post.
Below is my AngularJS code:
var headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post(this.baseUrl + '/user/authenticate-user',
JSON.stringify({"email": email, "password": password}),
{
headers: headers
}).map((response: Response) => {}
});
Below is my route in web.php...
Route::post('user/authenticate-user', 'UserController#postLogin');
I have written postLogin method in UserController controller.
just first simply check weather you reach at your route or not Route::post('user/authenticate-user', function(){
dd(Input::all());
});
it this will print all your sent data then check your function weather above it you mistakenly forgot to add ";" some where so he can't understand where you postLogin function start
think this will help you
I'm using grails 2.3.7 with SpringSecurityCore 2.0 .. I have two separate signon screens tailored for specific devices with the appropriate one triggered by accessing a specific controller. To do this I customized the loginController ..
/**
* Show the login page.
*/
def auth() {
def config = SpringSecurityUtils.securityConfig
if (springSecurityService.isLoggedIn()) {
redirect uri: config.successHandler.defaultTargetUrl
return
}
String whereFrom = session.SPRING_SECURITY_SAVED_REQUEST.requestURI
def rdt = whereFrom.contains('RDT')
// Redirect for RDT as required ..
String view = rdt ? 'rauth' : 'auth'
String postUrl = "${request.contextPath}${config.apf.filterProcessesUrl}"
session.rdt = rdt
render view: view, model: [postUrl: postUrl,
rememberMeParameter: config.rememberMe.parameter]
}
which seems to work well .. On logout I want again to redirect to an appropriate screen .. I'm trying to use the session attribute I store on login along with a (admittedly old) link I found (http://grails.1312388.n4.nabble.com/Parameter-quot-logoutSuccessUrl-quot-in-spring-security-core-td2264147.html) to redirect back to an appropriate page ..
/**
* Index action. Redirects to the Spring security logout uri.
*/
def index() {
if (!request.post && SpringSecurityUtils.getSecurityConfig().logout.postOnly) {
response.sendError HttpServletResponse.SC_METHOD_NOT_ALLOWED // 405
return
}
// TODO put any pre-logout code here
def rdt = session.rdt
session.rdt = null
// redirect uri: "/j_spring_security_logout?spring-security-redirect=$logoutUrl"
if (rdt) {
def link = g.createLink(controller: "RDT")
def redirectUrl = "${SpringSecurityUtils.securityConfig.logout.filterProcessesUrl}?spring-security-redirect=${link}"
redirectStrategy.sendRedirect request, response, redirectUrl
} else {
redirectStrategy.sendRedirect request, response, SpringSecurityUtils.securityConfig.logout.filterProcessesUrl // '/j_spring_security_logout'
}
response.flushBuffer()
}
Both options return me to the 'default' auth login screen and not my alternate rauth one even with the addition of the extra parameter .. How can I route back to an appropriate screen ?? Thanks
In the end I manually set the session variables to null, invalidate the session and a standard redirect ... works ..
I am using grails-jaxrs for exposing an api which accepts multipart/form-data..
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(['application/json'])
#Path('/addMessage')
ChatMessage addChatMessageWithAttachment(#Context HttpServletRequest req) {
log.debug "> addChatMessageWithAttachment"
def fileStores = []
def chatMessage
GrailsWebRequest request = WebUtils.retrieveGrailsWebRequest()
def params = request.getParams()
if (!(params.messageBody.length() > 0)) {
log.error("Empty message body")
throw new LocalisedException(ErrorCode.CHAT_MESSAGE_CREATE_FAILED)
}
}
The implementation is working properly as expected. I am able to send form-data (with file and other parameters successfully.
Now I am trying to implement integration test for above logic.
I am using IntegrationTestCase to achieve this.. so my code snippet is as below:
class ChatMessageResourceV1Tests extends IntegrationTestCase{
//other implementation and setup ommited
#Test
void "Create new chat message for event id - customer user"() {
def headers = ['Content-Type': 'multipart/form-data', 'Accept': 'application/json']
def data = "My message..."
def cm = new ChatMessage(messageBody: data)
def content = "{'eventId':'$event.id','messageBody':'My message...'}"
sendRequest("/api/v1/chatMessage/addMessage", 'POST', headers, content.bytes)
assertEquals(200, response.status)
}
}
When I run the test.. I can see the call reaches inside the API method.. But however, the parameter messageBody is coming as null and exception is being thrown.
I have tried every possible combination of test.. But no luck.
Any help would be appreciated.
I'm trying to redirect the url of my app in node.js in this way:
// response comes from the http server
response.statusCode = 302;
response.setHeader("Location", "/page");
response.end();
But the current page is mixed with the new one, it looks strange :| My solution looked totally logical, I don't really know why this happens, but if I reload the page after the redirection it works.
Anyway what's the proper way to do HTTP redirects in node?
Looks like express does it pretty much the way you have. From what I can see the differences are that they push some body content and use an absolute url.
See the express response.redirect method:
https://github.com/visionmedia/express/blob/master/lib/response.js#L335
// Support text/{plain,html} by default
if (req.accepts('html')) {
body = '<p>' + http.STATUS_CODES[status] + '. Redirecting to ' + url + '</p>';
this.header('Content-Type', 'text/html');
} else {
body = http.STATUS_CODES[status] + '. Redirecting to ' + url;
this.header('Content-Type', 'text/plain');
}
// Respond
this.statusCode = status;
this.header('Location', url);
this.end(body);
};
server = http.createServer(
function(req, res)
{
url ="http://www.google.com";
body = "Goodbye cruel localhost";
res.writeHead(301, {
'Location': url,
'Content-Length': body.length,
'Content-Type': 'text/plain' });
res.end(body);
});
Yes it should be full url in setHeader.
res.statusCode = 302;
res.setHeader('Location', 'http://' + req.headers['host'] + ('/' !== req.url)? ( '/' + req.url) : '');
res.end();
What happens if you change it to 307 instead?
This issue may also depend on the type of request you are handling. A POST request cannot be redirected using the header. For example, a first-time visitor from to your app in FB will most-likely be coming via a "signed request" POST and therefore a redirect will not work.