如何使用 Guardian 同时通过 api 和会话对用户进行身份验证?
How can I authenticate a user via api and session simultaneously using Guardian?
我正在尝试通过 api 对用户进行身份验证,但我还想确保他们在刷新页面时仍保持身份验证状态。
Guardian.Plug.sign_in 似乎符合在 cookie 中存储用户身份验证的要求,但是当我通过我的 api.
进行身份验证时,cookie 没有设置
这确实有效:
conn
|> Guardian.Plug.sign_in(user)
|> redirect(to: root_path(conn, :index))
按此顺序使用这些管道:
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :browser_session do
plug Guardian.Plug.VerifySession
plug Guardian.Plug.LoadResource
end
这不是:
conn
|> Guardian.Plug.sign_in(user)
|> render("session.json")
按此顺序使用这些管道:
pipeline :api do
plug :accepts, ["json"]
plug Guardian.Plug.VerifyHeader
plug Guardian.Plug.LoadResource
end
pipeline :api_session do
plug :fetch_session
plug :fetch_flash
plug :put_secure_browser_headers
plug Guardian.Plug.VerifySession
end
如果您想使用相同的身份验证来管理您的 API 和浏览器,那么只需使用浏览器身份验证即可。例如,如果您的端点是一个 graphql 中间件,那么您的 NetworkLayer 必须配置如下:
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer('http://example.com/graphql', {
credentials: 'same-origin',
})
);
这样您的 Relay 应用程序将使用与您 loaded/refreshed 页面相同的 session。这和老派 Ajax 的东西一样。
另一方面,如果您的所有 front-end 都将基于在浏览器中呈现的 Javascript 客户端(即:React&Relay),那么您可以使用 Phoenix 控制器来呈现Javascript 页面将执行,并且完全依赖于 JWT。例如,使用 react-router,您可以执行以下操作:
function requireAuth(nextState, replace) {
if (!auth.loggedIn()) {
replace({
pathname: '/session/new',
state: { nextPathname: nextState.location.pathname }
})
}
}
ReactDOM.render(
<Router history={browserHistory}
render={applyRouterMiddleware(useRelay)}
environment={Relay.Store}>
<Route path="/" component={Hello}/>
<Route path="/session/new" component={Login}/>
<Route path="/admin" component={AdminLayout} onEnter={requireAuth}>
<IndexRoute component={HelloAdmin}/>
<Route path="star-wars" component={StarWarsApp} queries={StarWarsQueries}/>
<Route path="graphiql" component={GraphiQL} />
</Route>
</Router>,
document.getElementById('react-root')
);
您的身份验证将只检查 JWT 的存在(可能在 localStorage 中)。当您请求 API 时,您必须在授权 header 中发送您的 JWT。又是一个中继示例:
const token = localStorage.getItem('token');
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer(GRAPHQL_URL, {
headers: {
Authorization: 'Bearer ' + token
}
})
);
然后你就可以在后端使用 Guardian 的东西了。请记住,在这个完整的 API 选项中,呈现登录页面的逻辑将在 front-end.
中完全实现
我正在尝试通过 api 对用户进行身份验证,但我还想确保他们在刷新页面时仍保持身份验证状态。
Guardian.Plug.sign_in 似乎符合在 cookie 中存储用户身份验证的要求,但是当我通过我的 api.
进行身份验证时,cookie 没有设置这确实有效:
conn
|> Guardian.Plug.sign_in(user)
|> redirect(to: root_path(conn, :index))
按此顺序使用这些管道:
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :browser_session do
plug Guardian.Plug.VerifySession
plug Guardian.Plug.LoadResource
end
这不是:
conn
|> Guardian.Plug.sign_in(user)
|> render("session.json")
按此顺序使用这些管道:
pipeline :api do
plug :accepts, ["json"]
plug Guardian.Plug.VerifyHeader
plug Guardian.Plug.LoadResource
end
pipeline :api_session do
plug :fetch_session
plug :fetch_flash
plug :put_secure_browser_headers
plug Guardian.Plug.VerifySession
end
如果您想使用相同的身份验证来管理您的 API 和浏览器,那么只需使用浏览器身份验证即可。例如,如果您的端点是一个 graphql 中间件,那么您的 NetworkLayer 必须配置如下:
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer('http://example.com/graphql', {
credentials: 'same-origin',
})
);
这样您的 Relay 应用程序将使用与您 loaded/refreshed 页面相同的 session。这和老派 Ajax 的东西一样。
另一方面,如果您的所有 front-end 都将基于在浏览器中呈现的 Javascript 客户端(即:React&Relay),那么您可以使用 Phoenix 控制器来呈现Javascript 页面将执行,并且完全依赖于 JWT。例如,使用 react-router,您可以执行以下操作:
function requireAuth(nextState, replace) {
if (!auth.loggedIn()) {
replace({
pathname: '/session/new',
state: { nextPathname: nextState.location.pathname }
})
}
}
ReactDOM.render(
<Router history={browserHistory}
render={applyRouterMiddleware(useRelay)}
environment={Relay.Store}>
<Route path="/" component={Hello}/>
<Route path="/session/new" component={Login}/>
<Route path="/admin" component={AdminLayout} onEnter={requireAuth}>
<IndexRoute component={HelloAdmin}/>
<Route path="star-wars" component={StarWarsApp} queries={StarWarsQueries}/>
<Route path="graphiql" component={GraphiQL} />
</Route>
</Router>,
document.getElementById('react-root')
);
您的身份验证将只检查 JWT 的存在(可能在 localStorage 中)。当您请求 API 时,您必须在授权 header 中发送您的 JWT。又是一个中继示例:
const token = localStorage.getItem('token');
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer(GRAPHQL_URL, {
headers: {
Authorization: 'Bearer ' + token
}
})
);
然后你就可以在后端使用 Guardian 的东西了。请记住,在这个完整的 API 选项中,呈现登录页面的逻辑将在 front-end.
中完全实现