Using JWT to do the authentication of RESTful API-go language implementation

Source: Internet
Author: User

Using JWT to do the authentication of RESTful API-go language implementation

Building a restful API with Golang and MongoDB has already implemented a simple RESTful API application, but for some API interfaces that require authorization before they can be accessed, jwt a token-based authentication is used in this article about jwt Please visit JWT for detailed instructions, and there are libraries implemented in each language, please use the corresponding version as needed.

Image

The interface needs to be installed first jwt-gogo get github.com/dgrijalva/jwt-go

Added sign-in interface and token creation at login

    • Customize the return results and encapsulatehelper/utils.go
type Response struct {    Code int         `json:"code"`    Msg  string      `json:"msg"`    Data interface{} `json:"data"`}func ResponseWithJson(w http.ResponseWriter, code int, payload interface{}) {    response, _ := json.Marshal(payload)    w.Header().Set("Content-Type", "application/json")    w.WriteHeader(code)    w.Write(response)}
    • Modelmodels/user.go
type User struct {    UserName string `bson:"username" json:"username"`    Password string `bson:"password" json:"password"`}type JwtToken struct {    Token string `json:"token"`}
    • Controllercontrollers/user.go
Func Register (w http. Responsewriter, R *http. Request) {var user models. User ERR: = json. Newdecoder (R.body). Decode (&user) if err! = Nil | | User. UserName = = "" | | User. Password = = "" {Helper. Responsewithjson (W, http. Statusbadrequest, Helper. Response{code:http. Statusbadrequest, MSG: "Bad Params"}) return} err = models. Insert (DB, collection, user) if err! = Nil {helper. Responsewithjson (W, http. Statusinternalservererror, Helper. Response{code:http. Statusinternalservererror, MSG: "Internal Error"})}}func Login (w http. Responsewriter, R *http. Request) {var user models. User ERR: = json. Newdecoder (R.body). Decode (&user) if err! = Nil {helper. Responsewithjson (W, http. Statusbadrequest, Helper. Response{code:http. Statusbadrequest, MSG: "Bad Params"})} exist: = models. Isexist (DB, Collection, Bson. m{"username": User. UserName}) if exist {token, _: = Auth. Generatetoken (&user)       Helper. Responsewithjson (W, http. Statusok, Helper. Response{code:http. Statusok, Data:models. Jwttoken{token:token}})} else {helper. Responsewithjson (W, http. Statusnotfound, Helper. Response{code:http. Statusnotfound, MSG: "The User not Exist"})}}
    • Generate tokensauth/middleware.go
func GenerateToken(user *models.User) (string, error) {    token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{        "username": user.UserName,    //"exp":      time.Now().Add(time.Hour * 2).Unix(),// 可以添加过期时间    })    return token.SignedString([]byte("secret"))//对应的字符串请自行生成,最后足够使用加密后的字符串}

HTTP middleware

The middleware of Go HTTP is very simple to implement, just to implement a function signature as func (http. Handler) http. The handler function can be.

func middlewareHandler(next http.Handler) http.Handler{    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request){        // 执行handler之前的逻辑        next.ServeHTTP(w, r)        // 执行完毕handler后的逻辑    })}

We use the MUX as a route, which natively supports the addition of middleware in the route, transforming the previous routing logic

routes/routes.go

type Route struct {    Method     string    Pattern    string    Handler    http.HandlerFunc    Middleware mux.MiddlewareFunc //添加中间件}func NewRouter() *mux.Router {    router := mux.NewRouter()    for _, route := range routes {        r := router.Methods(route.Method).            Path(route.Pattern)    //如果这个路由有中间件的逻辑,需要通过中间件先处理一下        if route.Middleware != nil {            r.Handler(route.Middleware(route.Handler))        } else {            r.Handler(route.Handler)        }    }    return router}

Middleware for implementing authentication

auth/middleware.go

Verify that the information is placed in the http Header

Func tokenmiddleware (next http. Handler) http. Handler {return HTTP. Handlerfunc (Func (w http. Responsewriter, R *http. Request) {tokenstr: = R.header.get ("authorization") if Tokenstr = = "" {Helper. Responsewithjson (W, http. statusunauthorized, Helper. Response{code:http. statusunauthorized, MSG: "Not Authorized"})} else {token, _: = JWT. Parse (Tokenstr, func (token *JWT). token) (interface{}, error) {If _, OK: = token. Method. (*JWT. SIGNINGMETHODHMAC);!ok {Helper. Responsewithjson (W, http. statusunauthorized, Helper. Response{code:http. statusunauthorized, MSG: "Not Authorized"}) return nil, FMT. Errorf ("Not Authorization")} Return []byte ("secret"), nil}) if!toke N.valid {Helper. Responsewithjson (W, http. statusunauthorized, Helper. Response{code:http. Statusunauthorized, MSG: "Not Authorized"})} else {next. Servehttp (W, R)}})}

Adding middleware to routes that require validation

register("GET", "/movies", controllers.AllMovies, auth.TokenMiddleware) //需要中间件逻辑register("GET", "/movies/{id}", controllers.FindMovie, nil)//不需要中间件

Verify

    • After logging in, return the corresponding token information
//请求 post http://127.0.0.1:8080/login//返回{    "code": 200,    "msg": "",    "data": {        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNvZGVybWluZXIifQ.pFzJLU8vnzWiweFKzHRsawyWA2jfuDIPlDU4zE92O7c"    }}
    • Get all the movie information when
//请求 post http://127.0.0.1:8080/movies在 Header中设置 "authorization":token如果没有设置header会报 401 错误{    "code": 401,    "msg": "not authorized",    "data": null}

SOURCE Github

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.