mirror of
https://github.com/casdoor/casdoor.git
synced 2025-05-23 02:35:49 +08:00
feat: add geetest captcha (#953)
This commit is contained in:
parent
d55ae7d1d2
commit
4ea482223d
82
captcha/geetest.go
Normal file
82
captcha/geetest.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
// Copyright 2022 The Casdoor Authors. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package captcha
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/casdoor/casdoor/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
const GEETESTCaptchaVerifyUrl = "http://gcaptcha4.geetest.com/validate"
|
||||||
|
|
||||||
|
type GEETESTCaptchaProvider struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGEETESTCaptchaProvider() *GEETESTCaptchaProvider {
|
||||||
|
captcha := &GEETESTCaptchaProvider{}
|
||||||
|
return captcha
|
||||||
|
}
|
||||||
|
|
||||||
|
func (captcha *GEETESTCaptchaProvider) VerifyCaptcha(token, clientSecret string) (bool, error) {
|
||||||
|
pathData, err := url.ParseQuery(token)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
signToken := util.GetHmacSha256(clientSecret, pathData["lot_number"][0])
|
||||||
|
|
||||||
|
formData := make(url.Values)
|
||||||
|
formData["lot_number"] = []string{pathData["lot_number"][0]}
|
||||||
|
formData["captcha_output"] = []string{pathData["captcha_output"][0]}
|
||||||
|
formData["pass_token"] = []string{pathData["pass_token"][0]}
|
||||||
|
formData["gen_time"] = []string{pathData["gen_time"][0]}
|
||||||
|
formData["sign_token"] = []string{signToken}
|
||||||
|
captchaId := pathData["captcha_id"][0]
|
||||||
|
|
||||||
|
cli := http.Client{Timeout: time.Second * 5}
|
||||||
|
resp, err := cli.PostForm(fmt.Sprintf("%s?captcha_id=%s", GEETESTCaptchaVerifyUrl, captchaId), formData)
|
||||||
|
if err != nil || resp.StatusCode != 200 {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type captchaResponse struct {
|
||||||
|
Result string `json:"result"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
}
|
||||||
|
captchaResp := &captchaResponse{}
|
||||||
|
err = json.Unmarshal(body, captchaResp)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if captchaResp.Result == "success" {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, errors.New(captchaResp.Reason)
|
||||||
|
}
|
@ -27,6 +27,8 @@ func GetCaptchaProvider(captchaType string) CaptchaProvider {
|
|||||||
return NewHCaptchaProvider()
|
return NewHCaptchaProvider()
|
||||||
} else if captchaType == "Aliyun Captcha" {
|
} else if captchaType == "Aliyun Captcha" {
|
||||||
return NewAliyunCaptchaProvider()
|
return NewAliyunCaptchaProvider()
|
||||||
|
} else if captchaType == "GEETEST" {
|
||||||
|
return NewGEETESTCaptchaProvider()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,9 @@ package util
|
|||||||
import (
|
import (
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetHmacSha1(keyStr, value string) string {
|
func GetHmacSha1(keyStr, value string) string {
|
||||||
@ -28,3 +30,10 @@ func GetHmacSha1(keyStr, value string) string {
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetHmacSha256(key string, data string) string {
|
||||||
|
mac := hmac.New(sha256.New, []byte(key))
|
||||||
|
mac.Write([]byte(data))
|
||||||
|
|
||||||
|
return hex.EncodeToString(mac.Sum(nil))
|
||||||
|
}
|
||||||
|
@ -122,6 +122,10 @@ export const OtherProviderInfo = {
|
|||||||
"Aliyun Captcha": {
|
"Aliyun Captcha": {
|
||||||
logo: `${StaticBaseUrl}/img/social_aliyun.png`,
|
logo: `${StaticBaseUrl}/img/social_aliyun.png`,
|
||||||
url: "https://help.aliyun.com/product/28308.html",
|
url: "https://help.aliyun.com/product/28308.html",
|
||||||
|
},
|
||||||
|
"GEETEST": {
|
||||||
|
logo: `${StaticBaseUrl}/img/social_geetest.png`,
|
||||||
|
url: "https://www.geetest.com",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -615,6 +619,7 @@ export function getProviderTypeOptions(category) {
|
|||||||
{id: "reCAPTCHA", name: "reCAPTCHA"},
|
{id: "reCAPTCHA", name: "reCAPTCHA"},
|
||||||
{id: "hCaptcha", name: "hCaptcha"},
|
{id: "hCaptcha", name: "hCaptcha"},
|
||||||
{id: "Aliyun Captcha", name: "Aliyun Captcha"},
|
{id: "Aliyun Captcha", name: "Aliyun Captcha"},
|
||||||
|
{id: "GEETEST", name: "GEETEST"},
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
|
@ -25,7 +25,7 @@ export const CaptchaWidget = ({captchaType, subType, siteKey, clientSecret, onCh
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
switch (captchaType) {
|
switch (captchaType) {
|
||||||
case "reCAPTCHA":
|
case "reCAPTCHA": {
|
||||||
const reTimer = setInterval(() => {
|
const reTimer = setInterval(() => {
|
||||||
if (!window.grecaptcha) {
|
if (!window.grecaptcha) {
|
||||||
loadScript("https://recaptcha.net/recaptcha/api.js");
|
loadScript("https://recaptcha.net/recaptcha/api.js");
|
||||||
@ -39,7 +39,8 @@ export const CaptchaWidget = ({captchaType, subType, siteKey, clientSecret, onCh
|
|||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
break;
|
break;
|
||||||
case "hCaptcha":
|
}
|
||||||
|
case "hCaptcha": {
|
||||||
const hTimer = setInterval(() => {
|
const hTimer = setInterval(() => {
|
||||||
if (!window.hcaptcha) {
|
if (!window.hcaptcha) {
|
||||||
loadScript("https://js.hcaptcha.com/1/api.js");
|
loadScript("https://js.hcaptcha.com/1/api.js");
|
||||||
@ -53,7 +54,8 @@ export const CaptchaWidget = ({captchaType, subType, siteKey, clientSecret, onCh
|
|||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
break;
|
break;
|
||||||
case "Aliyun Captcha":
|
}
|
||||||
|
case "Aliyun Captcha": {
|
||||||
const AWSCTimer = setInterval(() => {
|
const AWSCTimer = setInterval(() => {
|
||||||
if (!window.AWSC) {
|
if (!window.AWSC) {
|
||||||
loadScript("https://g.alicdn.com/AWSC/AWSC/awsc.js");
|
loadScript("https://g.alicdn.com/AWSC/AWSC/awsc.js");
|
||||||
@ -76,6 +78,33 @@ export const CaptchaWidget = ({captchaType, subType, siteKey, clientSecret, onCh
|
|||||||
}
|
}
|
||||||
}, 300);
|
}, 300);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case "GEETEST": {
|
||||||
|
let getLock = false;
|
||||||
|
const gTimer = setInterval(() => {
|
||||||
|
if (!window.initGeetest4) {
|
||||||
|
loadScript("https://static.geetest.com/v4/gt4.js");
|
||||||
|
}
|
||||||
|
if (window.initGeetest4 && siteKey && !getLock) {
|
||||||
|
const captchaId = String(siteKey);
|
||||||
|
window.initGeetest4({
|
||||||
|
captchaId,
|
||||||
|
product: "float",
|
||||||
|
}, function(captchaObj) {
|
||||||
|
if (!getLock) {
|
||||||
|
captchaObj.appendTo("#captcha");
|
||||||
|
getLock = true;
|
||||||
|
}
|
||||||
|
captchaObj.onSuccess(function() {
|
||||||
|
const result = captchaObj.getValidate();
|
||||||
|
onChange(`lot_number=${result.lot_number}&captcha_output=${result.captcha_output}&pass_token=${result.pass_token}&gen_time=${result.gen_time}&captcha_id=${siteKey}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
clearInterval(gTimer);
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user