dony113407 2015-03-31 03:04
浏览 48
已采纳

马丁尼社交网络vk auth

I am trying to use vk auth with martini. But have error on compile:

/goPath/vkAuthTry2.go:38: undefined: YourRedirectFunc

The question is how to define YourRedirectFunc function. Or if ask more widely I need working example of martini app with vk social network authentication or if even more widely an example of any golang website using vk authentication.

Full code:

package main

import (
    "github.com/go-martini/martini"
    "github.com/yanple/vk_api"
    "net/http"
)

var api vk_api.Api

func prepareMartini() *martini.ClassicMartini {
    m := martini.Classic()
    m.Get("/somePage", func(w http.ResponseWriter, r *http.Request) {
        //  And receive token on the special method (redirect uri)
        currentUrl := r.URL.RequestURI() // for example "yoursite.com/get_access_token#access_token=3304fdb7c3b69ace6b055c6cba34e5e2f0229f7ac2ee4ef46dc9f0b241143bac993e6ced9a3fbc111111&expires_in=0&user_id=1"
        accessToken, userId, expiresIn, err := vk_api.ParseResponseUrl(currentUrl)
        if err != nil {
            panic(err)
        }
        api.AccessToken = accessToken
        api.UserId = userId
        api.ExpiresIn = expiresIn
        w.Write([]byte("somePage"))
    })
    return m
}

func main() {
    authUrl, err := api.GetAuthUrl(
        "domain.com/method_get_access_token", // redirect URI
        "token",        // response type
        "4672050",      // client id
        "wall,offline", // permissions https://vk.com/dev/permissions
    )
    if err != nil {
        panic(err)
    }
    YourRedirectFunc(authUrl)
    prepareMartini().Run()
}

Update

I edited my code according to @Elwinar's answer:

package main

import (
    "fmt"
    "github.com/go-martini/martini"
    "github.com/yanple/vk_api"
    "net/http"
)

var api vk_api.Api

func prepareMartini() *martini.ClassicMartini {
    m := martini.Classic()
    // This handler redirect the request to the vkontact system, which
    // will perform the authentification then redirect the request to
    // the URL we gave as the first paraemeter of the GetAuthUrl method
    // (treated by the second handler)
    m.Get("/vk/auth", func(w http.ResponseWriter, r *http.Request) {
        var api vk_api.Api
        authUrl, err := api.GetAuthUrl("http://localhost:3000/vk/token", "token", "4672050", "wall,offline")
        if err != nil {
            panic(err)
        }

        http.Redirect(w, r, authUrl, http.StatusFound)
    })

    // This handler is the one that get the actual authentification
    // information from the vkontact api. You get the access token,
    // userid and expiration date of the authentification session.
    // You can do whatever you want with them, generally storing them
    // in session to be able to get the actual informations later using
    // the access token.
    m.Get("/vk/token", func(w http.ResponseWriter, r *http.Request) {
        accessToken, userId, expiresIn, err := vk_api.ParseResponseUrl(r.URL.String())
        if err != nil {
            panic(err)
        }
        fmt.Println(accessToken)
        fmt.Println(userId)
        fmt.Println(expiresIn)
    })
    return m
}

func main() {
    prepareMartini().Run()
}

now no complie errors, but still cannot login. When I opened http://localhost:3000/vk/auth I was redirected on page...

https://oauth.vk.com/authorize?client_id=MY_APP_ID&redirect_uri=localhost%3A3000%2Fvk%2Ftoken&response_type=token&scope=wall%2Coffline

... and got the following browser output:

{"error":"invalid_request","error_description":"redirect_uri is incorrect, check application domain in the settings page"}

Of course instead of 4672050 I pasted my app id. This app was specially generated for localhost:3000. Maybe I need to paste somewhere my private key for oauth like pYFR2Xojlkad87880dLa.

Update 2

@qwertmax's answer almost works. I have successfully logged in by vk, but my code prints empty lines instead of userId and another user information:

 accessToken, userId, expiresIn, err := vk_api.ParseResponseUrl(r.URL.String())

fmt.Println(accessToken)
fmt.Println(userId)
fmt.Println(expiresIn)
  • 写回答

3条回答 默认 最新

  • donglu9134 2015-05-27 14:33
    关注

    Thanks for answer, I added example @qwertmax and fixed bug for parse fragment of url. Please update package and see example.

    package main
    // Thanks @qwertmax for this example
    // (http://stackoverflow.com/questions/29359907/social-network-vk-auth-with-martini)
    
    
    import (
        "log"
        "github.com/go-martini/martini"
        "github.com/yanple/vk_api"
        "net/http"
    )
    
    var api vk_api.Api
    
    func prepareMartini() *martini.ClassicMartini {
        m := martini.Classic()
    
        m.Get("/vk/auth", func(w http.ResponseWriter, r *http.Request) {
            authUrl, err := api.GetAuthUrl(
            "http://localhost:3000/vk/token",
            "app client id",
            "wall,offline")
    
            if err != nil {
                panic(err)
            }
    
            http.Redirect(w, r, authUrl, http.StatusFound)
        })
    
        m.Get("/vk/token", func(w http.ResponseWriter, r *http.Request) {
            code := r.URL.Query().Get("code")
    
            err := api.OAuth(
            "http://localhost:3000/vk/token", // redirect uri
            "app secret key",
            "app client id",
            code)
            if err != nil {
                panic(err)
            }
            http.Redirect(w, r, "/", http.StatusFound)
        })
    
        m.Get("/", func(w http.ResponseWriter, r *http.Request) string {
            if api.AccessToken == "" {
                return "<a href='/vk/auth'>Авторизоваться</a>"
            }
    
            // Api have: AccessToken, UserId, ExpiresIn
            log.Println("[LOG] martini.go:48 ->", api.AccessToken)
    
            // Make query
            params := make(map[string]string)
            params["domain"] = "yanple"
            params["count"] = "1"
    
            strResp, err := api.Request("wall.get", params)
            if err != nil {
                panic(err)
            }
            return strResp
        })
        return m
    }
    
    func main() {
        prepareMartini().Run()
    }
    

    Update 1: Update your package with command: go get -u github.com/yanple/vk_api Thanks for the comment.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 一直显示正在等待HID—ISP
  • ¥15 Python turtle 画图