简体   繁体   English

如何使用 JWT 令牌授权用户响应 asp net core web api。 何时使用授权标头不记名令牌?

[英]How to use JWT token to authorize user from react to asp net core web api. When to use autorization header bearer token?

Im building React app with Asp net core Web Api.我使用 Asp net core Web Api 构建 React 应用程序。 I implemented JWT authorization where I store jwt token in local storage.我实现了 JWT 授权,将 jwt 令牌存储在本地存储中。 Do I need to send it with every request to my webapi with Authorization header 'Bearer'?我是否需要将每个请求与授权标头“承载”一起发送到我的 webapi? And do I need to check the token in headers every time in my backend?我是否需要每次在后端检查标头中的令牌? I want my user to be authorized when making request but I dont know how to it.我希望我的用户在提出请求时获得授权,但我不知道如何授权。

This is my JwtService这是我的 JwtService

public class JWTAuthService
    {
        private readonly JwtTokenConfig jwtTokenConfig;
        private readonly ILogger<JWTAuthService> logger;

        public JWTAuthService(
            JwtTokenConfig jwtTokenConfig,
            ILogger<JWTAuthService> logger)
        {
            this.jwtTokenConfig = jwtTokenConfig;
            this.logger = logger;
        }

        public string BuildToken(Claim[] claims)
        {
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this.jwtTokenConfig.Secret));

            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken(
                    issuer: this.jwtTokenConfig.Issuer,
                    audience: this.jwtTokenConfig.Audience,
                    notBefore: DateTime.Now,
                    claims: claims,
                    expires: DateTime.Now.AddMinutes(this.jwtTokenConfig.AccessTokenExpiration),
                    signingCredentials: creds);

            return new JwtSecurityTokenHandler().WriteToken(token);
        }

        public string BuildRefreshToken()
        {
            var randomNumber = new byte[32];
            using var randomNumberGenerator = RandomNumberGenerator.Create();
            randomNumberGenerator.GetBytes(randomNumber);
            return Convert.ToBase64String(randomNumber);
        }

        public ClaimsPrincipal GetPrincipalFromToken(string token)
        {
            JwtSecurityTokenHandler tokenValidator = new();
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this.jwtTokenConfig.Secret));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var parameters = new TokenValidationParameters
            {
                ValidateAudience = false,
                ValidateIssuer = false,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = key,
                ValidateLifetime = false,
            };

            try
            {
                var principal = tokenValidator.ValidateToken(token, parameters, out var securityToken);

                if (!(securityToken is JwtSecurityToken jwtSecurityToken) || !jwtSecurityToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256, StringComparison.InvariantCultureIgnoreCase))
                {
                    this.logger.LogError($"Token validation failed");
                    return null;
                }

                return principal;
            }
            catch (Exception e)
            {
                this.logger.LogError($"Token validation failed: {e.Message}");
                return null;
            }
        }
    }
}

This is my auth where I return the user Id这是我返回用户 ID 的身份验证

 [HttpPost("user")]
        public string UserAuth([FromBody] string accessToken)
        {
            
            ClaimsPrincipal claimsPrincipal = this.jwtAuthService.GetPrincipalFromToken(accessToken);
            string id = claimsPrincipal.Claims.First(c => c.Type == "id").Value;

           var userId = JsonConvert.SerializeObject(id);
            return userId;

        }

This is my login component in react这是我在反应中的登录组件

const Login = () => {
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');
    const [redirect, setRedirect] = useState(false);

    const submit = async (e) => {
        e.preventDefault();

        const user = {
            username,
            password,
        };
        
        await fetch('https://localhost:44366/api/AppUsers/login', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            credentials: 'include',
            body: JSON.stringify(user),
        }).then(response => response.json()).then(res => {

            if (res.AccessToken) {
                localStorage.setItem("jwt", res.AccessToken);
            }
        })

        setRedirect(true);
    }

    if (redirect) {
        return <Redirect to="/" />
    }

here is return state

I have posts on my home page where user can submit comments.我的主页上有帖子,用户可以在其中提交评论。 I need userId to make the post request to my Api.我需要 userId 向我的 Api 发出发布请求。 First Im doing one request for getting the userId and then to post the comment.I know thats not the way and I need some help on how to do it.首先,我请求获取用户 ID,然后发布评论。我知道那不是方法,我需要一些有关如何操作的帮助。

const Card = (props) => {
  const [text, setText] = useState("");
  const [showMore, setShowMore] = useState(false);
  const [userId, setUserId] = useState();

  const {
    postId,
    key,
    profilePicture,
    image,
    comments,
    likedByText,
    likedByNumber,
    hours,
    content,
    title,
    accountName,
  } = props;

  const submitComment = (e, postId) => {
    e.preventDefault();

    const jwt = localStorage.getItem("jwt");
    const fetchUrl = `https://localhost:44366/api/AppUsers/user`;

    const fetchData = () => {
      fetch((fetchUrl),
        {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(jwt),
        })
        .then((res) => res.json())
        .then((result) => setUserId(result))
        .catch((err) => {
          console.log(err);
        });
    };

    fetchData();

    const id = postId;
    const data = {
      Content: text,
      UserId: userId,
      PostId: id ,
    }

    fetch('https://localhost:44366/api/Comments/create', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        
      },
      body: JSON.stringify(data)
    })
      .catch((error) => {
        console.error('Error:', error);
      });

    setText('');
  }
  return (
    <div className="card" key={id}>
      <header>
        <Profile iconSize="big" image={profilePicture} accountName={accountName} />
      </header>
      <p className='text-center'>{title}</p>
      <p className='text-center'>  {content}</p>
      <ImageSlider slides={image} />

      <CardMenu />
      <div className="likedBy">
        <Profile iconSize="small" image={profilePicture} />
        <span>
          Liked by <strong>{likedByText}</strong> and{" "}
          <strong>{comments.Lenght} 50 others</strong>
        </span>
      </div>
      <div className="comments">
        {comments?.slice(0, 5).map((comment) => (

          <Comment
            key={comment.id}
            accountName={comment.User.FirstName ? comment.User.FirstName : null}
            comment={comment.Content}
          />
        )
        )}

        {showMore && comments?.slice(5).map((comment) => (
          <Comment
            key={comment.id}
            accountName={comment.User.FirstName ? comment.User.FirstName : null}
            comment={comment.Content}
          />
        ))}

        <button type="button" className="button" onClick={() => setShowMore(true)}>Show more comments</button>
      </div>
      
      <div className="timePosted">Before {hours} hours.</div>
      <form data={postId} onSubmit={e => submitComment(e, id)}>
        <div className="addComment">
          <textarea type="text" value={text} placeholder="Напишете коментар" className="commentText" onChange={(e) => setText(e.target.value)} />
          <button className="btn btn-primary" type="submit"  >Post</button>
        </div>
      </form>
    </div>
  );
}

export default Card;

Yes you need to add Authorization header 'Bearer' you can also create yourself a custom header and send the token there.是的,您需要添加 Authorization 标头“Bearer”,您也可以创建自己的自定义标头并将令牌发送到那里。

now in the backend you put a middleware that check the token before you reach it.现在在后端放置一个中间件,在您到达令牌之前检查令牌。

in the auth I personally use axios and you can configure there an api that auto insert the Header在身份验证中,我个人使用 axios,您可以在那里配置一个自动插入标题的 api

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JWT不记名令牌授权不起作用asp net core web api - JWT bearer token Authorization not working asp net core web api 如何使用两个asp.net web api的持票令牌 - How to use bearer token with two asp.net web api .NET Core API-中间件是否在标头中设置了JWT承载令牌? - .NET Core API - does the middleware set the JWT bearer token in the header? 使用Microsoft Graph令牌通过Jwt Bearer令牌保护ASP.NET Core Web API - Using Microsoft Graph token to secure ASP.NET Core Web API with Jwt Bearer tokens ASP.NET Core 3.1 不授权不记名令牌 - ASP.NET Core 3.1 doesn't authorize bearer token 如何使用 JWT 令牌检索 .NET Core API 中的当前用户数据? - How use a JWT token to retrieve current user data in .NET Core API? 实现Identity 2.1 + OWIN OAuth JWT承载令牌时如何从Web API控制器端点进行身份验证 - How to authenticate from Web API controller endpoint when implementing Identity 2.1 + OWIN OAuth JWT bearer token ASP.Net Core 3.0 JWT Bearer Token 没有可用的 SecurityTokenValidator - ASP.Net Core 3.0 JWT Bearer Token No SecurityTokenValidator available ASP.NET Core 6 JWT 不记名令牌异常 - ASP.NET Core 6 JWT bearer token exception ASP.NET Core JWT 不记名令牌自定义验证 - ASP.NET Core JWT Bearer Token Custom Validation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM