首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IHP可以用于带有JWT身份验证的应用后端吗?

IHP可以用于带有JWT身份验证的应用后端吗?
EN

Stack Overflow用户
提问于 2022-09-12 22:19:16
回答 1查看 43关注 0票数 0

是否有人使用IHP作为应用后端,如果是的话,需要做哪些更改才能做到这一点?是否有允许IHP进行jwt身份验证的JWT包或类似的东西?使用IHP作为应用后端的数字诱导支持吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-13 06:53:43

IHP本身现在只将JWT作为DataSync的一部分。但是,这里有一个用于数字诱导的自定义JWT实现:

代码语言:javascript
复制
{-# LANGUAGE AllowAmbiguousTypes #-}

module Application.Auth (initJWTAuthentication) where

import IHP.Prelude
import IHP.LoginSupport.Helper.Controller
import IHP.Controller.Session
import IHP.QueryBuilder
import IHP.Fetch
import IHP.ControllerSupport
import IHP.ModelSupport
import IHP.Controller.Context
import IHP.Controller.Param
import qualified Web.JWT as JWT
import qualified Data.ByteString as BS
import qualified Data.Maybe as Maybe
import qualified Data.Text as Text

{-# INLINE initJWTAuthentication #-}
initJWTAuthentication :: forall user normalizedModel.
        ( ?context :: ControllerContext
        , ?modelContext :: ModelContext
        , normalizedModel ~ NormalizeModel user
        , Typeable normalizedModel
        , Table normalizedModel
        , FromRow normalizedModel
        , PrimaryKey (GetTableName normalizedModel) ~ UUID
        , GetTableName normalizedModel ~ GetTableName user
        , FilterPrimaryKey (GetTableName normalizedModel)
        , KnownSymbol (GetModelName user)
    ) => IO ()
initJWTAuthentication = do
    let accessTokenQueryParam = (paramOrNothing  "access_token")
    let accessToken :: Maybe Text = accessTokenQueryParam <|> jwtFromAuthorizationHeader
    case accessToken of
        Just accessToken -> do
            signer <- fromContext @JWT.Signer
            let signature = JWT.decodeAndVerifySignature signer accessToken

            case signature of
                Just jwt -> do
                    let userId :: Id user = jwt
                            |> JWT.claims
                            |> JWT.sub
                            |> Maybe.fromMaybe (error "JWT missing sub")
                            |> JWT.stringOrURIToText
                            |> textToId

                    user <- fetchOneOrNothing userId
                    putContext user
                Nothing -> error "Invalid signature"
        Nothing -> pure ()

jwtFromAuthorizationHeader :: (?context :: ControllerContext) => Maybe Text
jwtFromAuthorizationHeader = do
    case getHeader "Authorization" of
        Just authHeader -> authHeader
                |> cs
                |> Text.stripPrefix "Bearer "
                |> Maybe.fromMaybe (error "Invalid format of Authorization header, expected 'Bearer <jwt>'")
                |> Just
        Nothing -> Nothing

把它放到Application/Auth.hs里。然后更改Web/FrontController.hs以调用initJWTAuthentication函数,如下所示:

代码语言:javascript
复制
instance InitControllerContext WebApplication where
    initContext = do
        setLayout defaultLayout

        initAuthentication @User
        initJWTAuthentication @User

之后,您可以向您的IHP应用程序(如http://myapp/SomeAction?access_token=<JWT here> )或通过设置Authorization HTTP头(如Authorization: Bearer <JWT here> )来发出API请求。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73695794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档