Comments (13)
@zw963 I'll release 1.2.0 with Crystal 1.5.0
from kemal.
I think it's because of the next
in the following, it breaks from if
block and runs into the else
condition
if current_user.nil?
puts "1"*100
env.redirect path.sign_in # <============== what we expected is redirect to "/auth/login-in" instead
puts "2"*100
next
else
can you remove the next
and try again?
from kemal.
can you remove the
next
and try again?
Sorry, remove next not work. the log is same when i visit "/"
[development] Kemal is ready to lead at http://0.0.0.0:3000
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
Exception: Missing hash key: "current_user_open_id" (KeyError)
from kemal.
Hi, @sdogruyol , i quite sure, env.redirect not work in before_all
do block.
anyway, i need one place to all request to ensure current_user is exists, if this feature
not work, it quite hard to write DRY code.
from kemal.
Hi, i found why this issue happen.
Following is my before_all code
before_all do |env|
next if env.request.path == path.sign_in
current_user = User.get_user_by_auth_token(env.session.string?("auth_token"))
if current_user.nil?
env.redirect path.sign_in
next
else
env.set "current_user", current_user
end
end
Following is my router block
get path.license_index do |env|
current_user = env.get("current_user").as(User)
licenses = LicenseQuery.new
render_with_current_user("license/index.ecr")
end
When i request path.license_index
, at first, will retrieve current_user in before_all block.
We assume current case, current_user is nil, so, code env.redirect path.sign_in
will run.
The really wired things is, before env.redirect
really happen, the request handle process still wil go into
router block, env.get("current_user").as(User)
will raise Missing hash key: "current_user" (KeyError)
in
this case, because i never set it in before_all.
so, why this issue is happen is discovered, how to fix that? maybe i do things wrong way?
Anyway, i don't think we should do env.get?("current_user") check in my request block is useful.
because if i need check it, i really don't need before_all!
What i expected just is, redirect early in before_all call.
But, for now, before_all just is a place do some common things, but still continue
.
I guess it caused by lazy? as describe by following
The Filter middleware is lazily added as soon as a call to after_X or before_X is made.
It will not even be instantiated unless a call to after_X or before_X is mad
from kemal.
@zw963 I think you would want to close the response immediately after redirection.
if current_user.nil?
puts "1"*100
env.redirect path.sign_in # <============== what we expected is redirect to "/auth/login-in" instead
env.response.close
puts "2"*100
next
else
env.session.string("current_user_open_id", current_user.open_id)
end
@sdogruyol I think it makes sense to close the response inside of the HTTP::Server::Context#redirect method, better to make it an optional parameter:
def redirect(url : String, status_code : Int32 = 302, *, body : String? = nil, close : Bool = true)
@response.headers.add "Location", url
@response.status_code = status_code
@response.print(body) if body
@response.close if close
end
Even with this, it would still go through all before filters, it only stops at the beginning of Kemal::RouteHandler#process_request because it short circuits if the response is already closed.
Maybe we can add something similar to HTTP::StaticFileHandler's fallthrough
option to filters.
from kemal.
@zw963 I think you would want to close the response immediately after redirection.
Yes, you are right.
from kemal.
Cool, my issue is solved! quite perfect.
before this, there is no easy way to use setted env in request handler.
e.g.
get path.home_index do |env|
current_user = env.get("current_user").as(User)
# ...
end
When i try to visit path.home_index directly without login in, will raise exception
because no "current_user" key get set before.
even, after i change to current_user = env.get?("current_user").as(User)
, it still not work.
because raise exception: " Exception: cast from Nil to User failed".
I really don't want add a if/else again for make current_user always work, even, i have done it in before_all.
Now, it works like a charm!!
Thanks for @sdogruyol , @cyangle , and all.
from kemal.
Do we consider release 1.1.3?
from kemal.
I'll release 1.2.0 with Crystal 1.5.0
Okay, that soulds reasonable, anyway, some default behavior in before_filter was changed.
from kemal.
@zw963 I'll release 1.2.0 with Crystal 1.5.0 +1
Forget to release 1.2.0 ?
from kemal.
Haha no @zw963 thanks for the ping
from kemal.
@zw963 there you go https://github.com/kemalcr/kemal/releases/tag/v1.2.0
from kemal.
Related Issues (20)
- content with layout seems duplicated HOT 1
- Unable to close websocket from the on_message handler
- Getting benchmark behavior I cannot explain (triggers malware detection) HOT 13
- Missing helpers method to define helper methods for use in route handlers and templates
- Proxying of large files fail on Crystal 1.3.x
- Changelog doesn't mention the removal of `kilt`
- Rendering HTML with layout file double renders the inner content HOT 1
- IPv6 support HOT 4
- Slang doesn't render anymore HOT 10
- When use content_for with yield_content, output duplicate page content. HOT 9
- [Question] What is the correct way to share a object(e.g. current_user) across kemal session HOT 3
- Internal API broken in Crystal nightly
- Logs are messed up in multithreaded mode HOT 2
- build failed with latest crystal HOT 5
- Error: undefined method 'modification_time' for Kemal::StaticFileHandler (Crystal 1.6.0) HOT 2
- Compilation issue with crystal 1.6 HOT 4
- Problem serving local files HOT 5
- MacOs Ci is broken HOT 5
- A simple hello world kemal app run on windows failed. (but compilation on github action successful) HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from kemal.