11use axum:: {
2- extract:: { FromRequestParts , Request , State } ,
2+ extract:: { FromRequestParts , Query , Request , State } ,
33 http:: StatusCode ,
44 middleware:: Next ,
55 response:: { IntoResponse , Response } ,
@@ -8,39 +8,51 @@ use axum_extra::{
88 TypedHeader ,
99 headers:: { Authorization , authorization:: Bearer } ,
1010} ;
11+ use serde:: { Deserialize , Serialize } ;
1112use tracing:: warn;
1213
1314use crate :: middlewares:: TokenVerify ;
14-
15+ #[ derive( Debug , Deserialize , Serialize ) ]
16+ struct Params {
17+ access_token : String ,
18+ }
1519pub async fn verify_token < T > ( State ( state) : State < T > , request : Request , next : Next ) -> Response
1620where
1721 T : TokenVerify + Clone + Send + Sync + ' static ,
1822{
1923 let ( mut parts, body) = request. into_parts ( ) ;
20- let req =
24+ let token =
2125 match TypedHeader :: < Authorization < Bearer > > :: from_request_parts ( & mut parts, & state) . await {
22- Ok ( TypedHeader ( Authorization ( bearer) ) ) => {
23- let token = bearer. token ( ) ;
24- match state. verify ( token) {
25- Ok ( claims) => {
26- let mut req = Request :: from_parts ( parts, body) ;
27- req. extensions_mut ( ) . insert ( claims) ;
28- req
29- }
30- Err ( err) => {
31- let msg = format ! ( "verify token failed:{:?}" , err) ;
32- warn ! ( msg) ;
33- return ( StatusCode :: FORBIDDEN , msg) . into_response ( ) ;
26+ Ok ( TypedHeader ( Authorization ( bearer) ) ) => bearer. token ( ) . to_string ( ) ,
27+ Err ( err) => {
28+ if err. is_missing ( ) {
29+ match Query :: < Params > :: from_request_parts ( & mut parts, & state) . await {
30+ Ok ( params) => params. access_token . to_string ( ) ,
31+ Err ( err) => {
32+ let msg = format ! ( "parse query failed:{}" , err) ;
33+ warn ! ( msg) ;
34+ return ( StatusCode :: UNAUTHORIZED , msg) . into_response ( ) ;
35+ }
3436 }
37+ } else {
38+ let msg = format ! ( "parse Authorization header failed: {}" , err) ;
39+ warn ! ( msg) ;
40+ return ( StatusCode :: UNAUTHORIZED , msg) . into_response ( ) ;
3541 }
3642 }
37- Err ( err) => {
38- let msg = format ! ( "parse Authorization header failed:{}" , err) ;
39- warn ! ( msg) ;
40- return ( StatusCode :: UNAUTHORIZED , msg) . into_response ( ) ;
41- }
4243 } ;
43-
44+ let req = match state. verify ( & token) {
45+ Ok ( claims) => {
46+ let mut req = Request :: from_parts ( parts, body) ;
47+ req. extensions_mut ( ) . insert ( claims) ;
48+ req
49+ }
50+ Err ( err) => {
51+ let msg = format ! ( "verify token failed:{:?}" , err) ;
52+ warn ! ( msg) ;
53+ return ( StatusCode :: FORBIDDEN , msg) . into_response ( ) ;
54+ }
55+ } ;
4456 next. run ( req) . await
4557}
4658
@@ -100,6 +112,11 @@ mod tests {
100112 . layer ( from_fn_with_state ( state. clone ( ) , verify_token :: < AppState > ) )
101113 . with_state ( state) ;
102114
115+ // no token
116+ let req = Request :: builder ( ) . uri ( "/" ) . body ( Body :: empty ( ) ) ?;
117+ let res = app. clone ( ) . oneshot ( req) . await ?;
118+ assert_eq ! ( res. status( ) , StatusCode :: UNAUTHORIZED ) ;
119+
103120 // good token
104121 let req = Request :: builder ( )
105122 . uri ( "/" )
@@ -108,17 +125,26 @@ mod tests {
108125 let res = app. clone ( ) . oneshot ( req) . await ?;
109126 assert_eq ! ( res. status( ) , StatusCode :: OK ) ;
110127
111- // no token
112- let req = Request :: builder ( ) . uri ( "/" ) . body ( Body :: empty ( ) ) ?;
113- let res = app. clone ( ) . oneshot ( req) . await ?;
114- assert_eq ! ( res. status( ) , StatusCode :: UNAUTHORIZED ) ;
115-
116128 // bad token
117129 let req = Request :: builder ( )
118130 . uri ( "/" )
119131 . header ( "Authorization" , "Bearer bad-token" )
120132 . body ( Body :: empty ( ) ) ?;
121- let res = app. oneshot ( req) . await ?;
133+ let res = app. clone ( ) . oneshot ( req) . await ?;
134+ assert_eq ! ( res. status( ) , StatusCode :: FORBIDDEN ) ;
135+
136+ // good token in query
137+ let req = Request :: builder ( )
138+ . uri ( format ! ( "/?access_token={token}" ) )
139+ . body ( Body :: empty ( ) ) ?;
140+ let res = app. clone ( ) . oneshot ( req) . await ?;
141+ assert_eq ! ( res. status( ) , StatusCode :: OK ) ;
142+
143+ // bad token
144+ let req = Request :: builder ( )
145+ . uri ( "/?access_token=bad-token" . to_string ( ) )
146+ . body ( Body :: empty ( ) ) ?;
147+ let res = app. clone ( ) . oneshot ( req) . await ?;
122148 assert_eq ! ( res. status( ) , StatusCode :: FORBIDDEN ) ;
123149
124150 Ok ( ( ) )
0 commit comments