横向检索 physicalai-jobs.com × humanoid-jobs.com,并可改写自己的职位·资料的MCP服务器。
读写24 + 自动化·分析·AI辅助12,共37个工具,可从 Claude Code / Cursor / HTTP API 调用。
这是对"AI 能直接看站点回答,为何还要经过 MCP?"的回答。一次性提问确实不需要,但在多站点横向·定期执行·严格过滤·大量获取方面会有差别。
| 观点 | Web访问(无MCP) | 经由MCP |
|---|---|---|
| 数据格式 | LLM 解析 HTML | 即时返回结构化JSON |
| 响应速度 | 数秒〜十几秒 | 约100ms(直连DB) |
| 2站点横向 | 分别巡回 humanoid 与 physicalai | 一次请求取双方(省略 site_code) |
| 过滤精度 | 仅限UI可显示范围 | 严格指定 salary_min / is_remote / prefecture 等 |
| 大量获取 | 抓取有被封锁风险 | 用 offset/limit 安全获取全部 |
| 抗站点改版 | 布局变更即失效 | 架构固定,稳定 |
| 定期执行(cron) | 每次启动浏览器 → 慢·重 | 一条 curl 即可 |
简言之,"只想现在问AI一件事"则不需要。若想嵌入自动化工作流、每天汇总、同时精确检索两个站点,MCP 会轻松得多。
AI 代理横向利用 physicalai-jobs.com / physicalai-jobs.com 职位数据的典型场景。
场景:"找人形或物理AI、年薪800万以上的远程职位"
动作:不指定站点直接调用 jobs_search 即同时检索两站。
场景:"列出所有类似 Boston Dynamics 的企业及其技术栈与职位数"
动作:companies_search → companies_detail 获取技术栈与招聘职种。
场景:"从文章中总结人形机器人行业的最新趋势"
动作:用 articles_search 取文章 → articles_detail 解析正文。
场景:"每周报告人形与物理AI职位数的变化"
动作:每周 cron 调用 stats 并发送到 Slack 即可。
从 Claude Code / Cursor 等支持 MCP 的 AI 三步接入 Jobs Navi。
/mypage/api-keys/ 生成密钥。仅读取可跳过。 .mcp.json) 或 Cursor (~/.cursor/mcp.json)。env 仅发行密钥者需要。 {
"mcpServers": {
"jobs-navi": {
"command": "npx",
"args": ["-y", "jobs-navi-mcp"],
"env": {
"JOBS_NAVI_API_KEY": "jn_your_api_key_here"
}
}
}
}
npx 自动获取 jobs-navi-mcp。重启后可识别37个工具。 # 读取示例
> 东京有机器人工程师、年薪800万以上的职位吗?> 把 Boston Dynamics 现在发布的职位全部告诉我
# 写入示例(需API密钥)
> 新建职位:高级机器人工程师,年薪900〜1500万,可远程> 把本公司资料说明更新为"2026年度B轮完成"> 把我的期望年薪改为900万,希望地点东京/神奈川
可通过 Claude Code / Cursor / HTTP API 三种方式接入。使用 HTTP API 也可从 ChatGPT Custom GPT Actions 调用。
将下列内容加入 .mcp.json 或 ~/.claude.json。JOBS_NAVI_API_KEY 在使用写入工具时必填(仅读取可省略)。
{
"jobs-navi": {
"command": "npx",
"args": ["-y", "jobs-navi-mcp"],
"env": {
"JOBS_NAVI_API_KEY": "jn_your_api_key_here"
}
}
}
将下列内容加入 ~/.cursor/mcp.json。
{
"mcpServers": {
"jobs-navi": {
"command": "npx",
"args": ["-y", "jobs-navi-mcp"],
"env": {
"JOBS_NAVI_API_KEY": "jn_your_api_key_here"
}
}
}
}
※ ChatGPT 不支持 Remote MCP。请从 Custom GPT Actions 调用 HTTP API。
# Custom GPT Actions 设置
# Server URL
https://physicalai-jobs.com/api/mcp.php
# Method: POST / Body 示例
{
"action": "jobs.search",
"params": { "keyword": "机器人" }
}
读取无需认证,写入需要 Authorization: Bearer jn_xxx。
# 读取(无需认证)
curl -X POST https://physicalai-jobs.com/api/mcp.php \
-H "Content-Type: application/json" \
-d '{"action": "jobs.search", "params": {"keyword": "机器人", "limit": 5}}'
# 写入(需API密钥)
curl -X POST https://physicalai-jobs.com/api/mcp.php \
-H "Authorization: Bearer jn_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"action": "jobs.publish", "params": {"id": 15}}'
12个读取工具无需认证。12个写入工具(创建·更新·公开职位,编辑企业/求职者资料等)需要 jn_xxx 格式的API密钥。
登录 physicalai-jobs.com 后, /mypage/api-keys/ 生成密钥。jn_ + 48位hex 共51字符,最多持有5个。
直接 HTTP 调用时放入 Authorization 头。Node.js MCP 通过 JOBS_NAVI_API_KEY 环境变量自动附加。
Authorization: Bearer jn_a1b2c3d4e5f6...
由于API密钥与发行用户绑定,仅可更新本公司职位 / 本人资料。他公司职位可读不可写。
详细规格·多层防御·速率限制请参阅 Security / Rate Limits 章节。
全部37个工具一览。点击展开参数与响应示例。省略 site_code 即横向检索。【需API密钥】的工具用于写入·操作本人资源。
MCP服务器健康检查。返回各站点的职位数·企业数·文章数。
无需参数。
响应示例{
"success": true,
"data": {
"status": "ok",
"sites": [
{
"site_code": "humanoid",
"name": "ヒューマノイドジョブ",
"domain": "humanoid-jobs.com",
"job_count": 1,
"company_count": 1,
"article_count": 0
},
{
"site_code": "physicalai",
"name": "フィジカルAIジョブ",
"domain": "physicalai-jobs.com",
"job_count": 0,
"company_count": 0,
"article_count": 0
}
]
}
}
返回横向检索对象的站点列表(代码·名称·域名·主题色)。
无需参数。
响应示例{
"success": true,
"data": [
{
"site_code": "humanoid",
"name": "ヒューマノイドジョブ",
"domain": "humanoid-jobs.com",
"specialty": "ロボット・ヒューマノイド人材特化",
"theme_color": "#0EA5E9"
},
{
"site_code": "physicalai",
"name": "フィジカルAIジョブ",
"domain": "physicalai-jobs.com",
"specialty": "フィジカルAI人材特化",
"theme_color": "#0d9488"
}
]
}
返回带职位数的职位分类列表。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
site_code |
string |
humanoid / physicalai(省略则横向检索) |
{
"success": true,
"data": [
{
"site_code": "humanoid",
"slug": "robot-engineer",
"name": "ロボットエンジニア",
"parent_slug": null,
"description": null,
"job_count": 1
}
]
}
按关键词·分类·都道府县·雇佣形态·远程·薪资过滤检索职位。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
site_code |
string |
humanoid / physicalai(省略则横向检索) | |
keyword |
string |
职位名·技能·企业名 | |
category_slug |
string |
分类slug | |
prefecture |
string |
都道府县名(例:东京都) | |
employment_type |
string |
full_time / part_time / contract / freelance / internship | |
is_remote |
boolean |
仅限可远程 true | |
salary_min |
number |
最低薪资(万日元) | |
limit |
number |
返回件数(default 20, max 100) | |
offset |
number |
偏移量(分页) |
{
"success": true,
"data": {
"total": 11,
"limit": 20,
"offset": 0,
"results": [
{
"id": 1,
"site_code": "humanoid",
"slug": "sample",
"title": "ヒューマノイドロボットエンジニア",
"employment_type": "full_time",
"prefecture": "東京都",
"is_remote": 0,
"salary_min": 6000000,
"salary_max": 12000000,
"company_name": "Sample Robotics"
}
]
}
}
获取职位详细信息(技能要求·福利·企业信息)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
职位ID(id 或 slug 必填) | |
slug |
string |
职位slug | |
site_code |
string |
指定slug时的目标站点 |
{
"success": true,
"data": {
"id": 1,
"title": "ヒューマノイドロボットエンジニア",
"description": "...",
"skills_required": [
"ROS2",
"C++",
"Python"
],
"company_name": "Sample Robotics",
"industry": "ロボティクス"
}
}
最新或精选职位列表(首页·小组件用)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
site_code |
string |
humanoid / physicalai | |
featured_only |
boolean |
仅精选职位 true | |
limit |
number |
返回件数 |
{
"success": true,
"data": [
{
"id": 1,
"title": "求人例",
"is_featured": 1,
"company_name": "Sample Robotics"
}
]
}
按关键词·行业过滤检索企业(含有效职位数)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
site_code |
string |
humanoid / physicalai | |
keyword |
string |
企业名·描述关键词 | |
industry |
string |
行业(例:机器人) | |
limit |
number |
返回件数(default 20, max 50) |
{
"success": true,
"data": [
{
"id": 1,
"company_name": "Sample Robotics",
"industry": "ロボティクス",
"active_job_count": 3
}
]
}
企业详细信息(技术栈·办公室图片·有效职位列表)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
企业ID(id 或 slug 必填) | |
slug |
string |
企业公开slug | |
site_code |
string |
指定slug时的目标站点 |
{
"success": true,
"data": {
"id": 1,
"company_name": "Sample Robotics",
"tech_stack": [
"ROS2",
"Python"
],
"active_jobs": [
{
"id": 1,
"title": "エンジニア"
}
]
}
}
按关键词·分类检索职位相关文章。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
site_code |
string |
humanoid / physicalai | |
keyword |
string |
标题·正文关键词 | |
category |
string |
文章分类 | |
limit |
number |
返回件数 |
{
"success": true,
"data": [
{
"id": 1,
"title": "業界の最新トレンド",
"category": "trend",
"view_count": 1234
}
]
}
获取含正文的文章详细信息。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
slug |
string |
YES | 文章slug |
site_code |
string |
目标站点 |
{
"success": true,
"data": {
"slug": "example",
"title": "記事タイトル",
"body": "記事本文..."
}
}
各站点统计信息(有效职位数·企业数·求职者数·应聘数·文章数)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
site_code |
string |
humanoid / physicalai |
{
"success": true,
"data": [
{
"site_code": "humanoid",
"active_jobs": 1,
"companies": 1,
"seekers": 0,
"applications": 0,
"articles": 0
}
]
}
面向企业的刊登套餐列表(套餐名·月费·职位额度·猎才额度·功能)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
site_code |
string |
humanoid / physicalai |
{
"success": true,
"data": [
{
"slug": "basic",
"name": "ベーシック",
"price_monthly": 30000,
"job_limit": 3
}
]
}
【需API密钥】返回与API密钥关联的用户信息。用于连接确认。
无需参数。
响应示例{
"success": true,
"data": {
"user_id": 2,
"email": "company@example.com",
"name": "テスト株式会社",
"role": "company"
}
}
【需API密钥 / 企业】返回本公司刊登中的职位列表(含draft)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
status |
string |
draft / active / closed / paused | |
limit |
number |
返回件数(default 30, max 100) |
{
"success": true,
"data": [
{
"id": 1,
"title": "求人",
"status": "active",
"view_count": 2
}
]
}
【需API密钥 / 企业】新建职位(以草稿状态保存)。用 jobs_publish 公开。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
title |
string |
YES | 职位标题 |
category_slug |
string |
YES | 分类slug |
description |
string |
YES | 职位说明正文 |
employment_type |
string |
full_time / part_time / contract / internship / remote | |
location |
string |
工作地点 | |
is_remote |
boolean |
可远程 | |
salary_min |
number |
最低年薪(日元) | |
salary_max |
number |
最高年薪(日元) | |
requirements |
string |
必备要求 | |
preferred |
string |
加分要求 | |
benefits |
string |
福利待遇 |
{
"success": true,
"message": "求人を下書きとして作成しました",
"data": {
"id": 15,
"slug": "job-abc123",
"status": "draft"
}
}
【需API密钥 / 企业】更新本公司职位(仅覆盖指定字段)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
YES | 要更新的职位ID |
title |
string |
标题 | |
salary_min |
number |
最低年薪 | |
salary_max |
number |
最高年薪 | |
description |
string |
正文 |
{
"success": true,
"message": "求人を更新しました",
"data": {
"id": 15
}
}
【需API密钥 / 企业】公开职位(draft → active)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
YES | 要公开的职位ID |
{
"success": true,
"message": "求人を公開しました",
"data": {
"id": 15,
"status": "active"
}
}
【需API密钥 / 企业】结束职位(active → closed)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
YES | 要结束的职位ID |
{
"success": true,
"message": "求人を終了しました",
"data": {
"id": 15,
"status": "closed"
}
}
【需API密钥 / 企业】获取本公司企业资料。
无需参数。
响应示例{
"success": true,
"data": {
"id": 1,
"company_name": "テスト株式会社",
"industry": "ロボティクス",
"employee_count": "50-100",
"website_url": "https://example.com"
}
}
【需API密钥 / 企业】更新本公司企业资料(未创建时新建)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
company_name |
string |
公司名(首次创建必填) | |
company_name_kana |
string |
假名 | |
industry |
string |
行业 | |
employee_count |
string |
员工数(例:50-100) | |
founded_year |
number |
成立年份 | |
website_url |
string |
官网URL | |
logo_url |
string |
Logo URL | |
description |
string |
公司说明 | |
address |
string |
地址 | |
phone |
string |
电话号码 | |
contact_person |
string |
负责人姓名 |
{
"success": true,
"message": "企業プロフィールを更新しました",
"data": {
"id": 1
}
}
【需API密钥 / 求职者】获取本人求职者资料。
无需参数。
响应示例{
"success": true,
"data": {
"id": 1,
"full_name": "テスト 太郎",
"prefecture": "東京都",
"experience_years": 5,
"desired_job_category": "robot-engineer",
"is_public": 1
}
}
【需API密钥 / 求职者】更新本人资料(未创建时新建)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
full_name |
string |
姓名(首次创建必填) | |
full_name_kana |
string |
假名 | |
birth_year |
number |
出生年(公历) | |
gender |
string |
male / female / other / prefer_not | |
prefecture |
string |
居住都道府县 | |
experience_years |
number |
经验年数 | |
current_status |
string |
employed / unemployed / student / other | |
desired_job_category |
string |
期望职位分类 | |
desired_salary_min |
number |
期望最低薪资(万日元) | |
resume_url |
string |
简历URL | |
pr_text |
string |
自我推荐 | |
is_public |
boolean |
是否向企业公开 |
{
"success": true,
"message": "求職者プロフィールを更新しました",
"data": {
"id": 1
}
}
【需API密钥】应聘列表。企业角色为对本公司职位的应聘,求职者角色为本人提交的应聘。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
limit |
number |
返回件数(default 30, max 100) |
{
"success": true,
"data": [
{
"id": 1,
"job_id": 1,
"job_title": "エンジニア",
"applicant_name": "テスト太郎",
"status": "pending",
"created_at": "2026-05-01 10:00:00"
}
]
}
【需API密钥 / 企业】更新对本公司职位的应聘状态。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
YES | 应聘ID |
status |
string |
YES | pending / reviewing / accepted / rejected / withdrawn |
{
"success": true,
"message": "応募ステータスを更新しました",
"data": {
"id": 1,
"status": "accepted"
}
}
【需API密钥】注册事件发生时以POST通知的Webhook(最多5个)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
url |
string |
YES | POST通知目标URL(必须https://) |
events |
array |
YES | new_application / application_status_changed / new_scout / job_published / job_closed |
label |
string |
识别用标签 |
{
"success": true,
"message": "Webhookを登録しました",
"data": {
"id": 1,
"url": "https://example.com/webhook",
"events": [
"new_application"
],
"secret": "abc123..."
}
}
【需API密钥】已注册Webhook列表(含调用次数·失败次数)。
无需参数。
响应示例{
"success": true,
"data": [
{
"id": 1,
"url": "https://example.com/webhook",
"events": [
"new_application"
],
"total_calls": 12,
"total_failures": 0
}
]
}
【需API密钥】删除Webhook。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
YES | Webhook ID |
{
"success": true,
"message": "Webhookを削除しました",
"data": {
"id": 1
}
}
【需API密钥】返回本人通知列表与未读数。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
unread_only |
boolean |
仅未读 true | |
limit |
number |
返回件数(default 30) |
{
"success": true,
"data": {
"unread_count": 3,
"items": [
{
"id": 1,
"type": "new_application",
"title": "新着応募がありました",
"is_read": 0
}
]
}
}
【需API密钥】将通知标记为已读(ID数组或 "all")。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ids |
mixed |
YES | ID数组 [1,2,3] 或 "all" |
{
"success": true,
"message": "全ての通知を既読にしました",
"data": {
"marked": "all"
}
}
【需API密钥 / 企业】批量创建职位(最多50件,各为draft状态)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
jobs |
array |
YES | 职位对象数组。各元素字段与 jobs_create 相同 |
{
"success": true,
"message": "全ての求人を作成しました",
"data": {
"created_count": 50,
"error_count": 0,
"created": [
{
"index": 0,
"id": 15,
"slug": "...",
"title": "..."
}
],
"errors": []
}
}
【需API密钥 / 企业】复制现有职位(draft状态)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
YES | 复制源职位ID |
title |
string |
新职位的标题 |
{
"success": true,
"message": "求人を複製しました",
"data": {
"id": 20,
"slug": "...",
"cloned_from": 15,
"status": "draft"
}
}
【需API密钥 / 企业】各职位的展示数·应聘数·收藏数·CVR。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
职位ID(省略则汇总全部职位) |
{
"success": true,
"data": {
"total_jobs": 5,
"total_views": 1234,
"total_applications": 42,
"overall_conversion": 3.41,
"jobs": [
{
"id": 1,
"title": "...",
"view_count": 500,
"application_count": 15,
"favorite_count": 23
}
]
}
}
【需API密钥 / 企业】以扁平结构返回应聘者信息(用于CSV转换)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
job_id |
number |
按特定职位筛选 | |
status |
string |
pending / reviewing / accepted / rejected / withdrawn |
{
"success": true,
"data": {
"count": 1,
"applicants": [
{
"id": 1,
"job_title": "ROS2エンジニア",
"applicant_email": "...",
"full_name": "テスト 太郎",
"prefecture": "東京都",
"status": "pending"
}
]
}
}
【需API密钥】从站内active职位计算薪资统计(中位数·四分位)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
category_slug |
string |
分类slug | |
prefecture |
string |
都道府县 | |
is_remote |
boolean |
仅限可远程 |
{
"success": true,
"data": {
"sample_size": 42,
"min": 3000000,
"max": 15000000,
"median": 7500000,
"p25": 5500000,
"p75": 10000000,
"avg": 7800000,
"unit": "円 / 年"
}
}
【需API密钥】返回与指定职位相似的职位(评分)。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
YES | 基准职位ID |
limit |
number |
返回件数(default 10, max 30) |
{
"success": true,
"data": {
"source_id": 15,
"results": [
{
"id": 18,
"title": "類似求人",
"similarity_score": 85,
"company_name": "Sample"
}
]
}
}
【需API密钥 / 企业】对本公司职位按10项评分。返回等级A-D与改进建议。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
number |
YES | 要评分的职位ID |
{
"success": true,
"data": {
"job_id": 15,
"score": 72,
"grade": "B",
"checks": [
{
"name": "タイトル20文字以上",
"pass": true,
"weight": 10
}
],
"summary": "良好。改善するともっと応募が増えます"
}
}
按企业返回带证券代码的招聘动量时间序列(招聘active/new数量推移与急增标志)。上市企业附ticker/交易所/国家。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
site_code |
string |
humanoid / physicalai / prompters(省略则横向) | |
ticker |
string |
按证券代码筛选(例:TSLA, 7203) | |
company |
string |
企业名关键词部分匹配 | |
period |
string |
weekly(默认)/ monthly | |
group_by |
string |
company(默认)/ ticker=按证券聚合(合并名称变体与多来源,members[]为明细) | |
limit |
number |
返回的最近期间数(default 26, max 104) | |
public_only |
boolean |
仅上市企业(ticker关联)true | |
min_delta_pct |
number |
急增判定的环比阈值%(default 50) |
{
"success": true,
"data": {
"as_of": "2026-05-19",
"period": "weekly",
"count": 12,
"top_surging": [
{
"company": "Tesla, Inc.",
"ticker": "TSLA",
"exchange": "NASDAQ",
"country": "US",
"active_delta_pct": 120,
"latest_active": 11,
"latest_new": 6
}
],
"series": [
{
"company": "Tesla, Inc.",
"ticker": "TSLA",
"exchange": "NASDAQ",
"country": "US",
"is_public": true,
"relation": "pure_play",
"site_code": "humanoid",
"latest_active": 11,
"prev_active": 5,
"active_delta_pct": 120,
"latest_new": 6,
"surge": true,
"points": [
{
"period_end": "2026-05-12",
"active_jobs": 5,
"new_jobs": 2
},
{
"period_end": "2026-05-19",
"active_jobs": 11,
"new_jobs": 6
}
]
}
]
}
}
为防止DoS·滥用,在 Nginx 层(L4)+ PHP 层(L7)实现两级速率限制。超限返回 HTTP 429 + Retry-After 头。
| 端点 | 限制 | Burst | 原因 |
|---|---|---|---|
/api/auth.php | 1 req/sec | 5 | 防暴力破解 |
/api/mcp.php | 5 req/sec | 20 | 防DoS(按IP) |
| 区分 | 限制 | 标识符 |
|---|---|---|
| 未认证Read | 60 req/min | IP地址 |
| 已认证Read | 200 req/min | API密钥ID |
| Write | 30 req/min | API密钥ID |
# HTTP/2 429
# Retry-After: 32
{
"success": false,
"message": "速率超限:write 每分钟最多30次",
"retry_after_sec": 32
}
客户端应等待 Retry-After 头的秒数后重试。
以多层防御实现生产运营所需的安全措施。
| 层 | 对策 | 内容 |
|---|---|---|
| L4 (Nginx) | 基于IP的速率限制 | 在到达PHP前丢弃过量请求 |
| HTTP Headers | 安全响应头 | HSTS / X-Content-Type-Options / Referrer-Policy / Permissions-Policy / CSP frame-ancestors |
| CORS | Origin 白名单 | 仅允许 physicalai-jobs.com / physicalai-jobs.com / kyuujin.prompters.jp / asi.co.jp |
| L7 认证 | API密钥校验 | Bearer + 正则匹配 + SHA-256哈希比对(抗时序攻击) |
| L7 速率限制 | 按API密钥 / IP | Read/Write 各自上限,超限 429 + Retry-After |
| 角色校验 | company / seeker 边界 | 角色违规 403,访问他人资源 404 |
| SQL Injection | PDO Prepared Statement | 全部查询使用占位符,LIMIT 等动态部分用 intval 转换 |
| SSRF 对策 | Webhook URL 校验 | localhost / 10.x / 192.168.x / 172.16-31.x / 169.254.x / link-local 拒绝 |
| 暴力破解 | 登录尝试追踪 | email 5次 / IP 20次失败锁定15分钟 |
| 会话 | Cookie 强化 | HttpOnly / Secure / SameSite=Lax |
| 错误信息 | 不暴露 | 异常详情仅在 error_log,客户端返回通用消息 |
| 项目 | 值 |
|---|---|
| 格式 | jn_ + hex 48位 = 51字符 |
| 熵 | 192位(24字节随机) |
| 存储形式 | SHA-256哈希(不存明文) |
| 范围 | 仅发行用户本人的资源 |
| 最大持有数 | 5个 / 用户 |
| 吊销 | 可即时 (/mypage/api-keys/) |
⚠️ 若密钥可能泄露请立即吊销。吊销后下次请求即返回401。
管理员可在以下仪表板实时监控: /admin/security/
日志保留30天(每日cron自动清理)。
如发现安全漏洞,请联系 security@physicalai-jobs.com 。我们将在公开前提供补丁。
出错时返回 success: false 与 HTTP 状态码。异常详情不向客户端暴露(仅通用消息)。
{
"success": false,
"message": "slug or id is required"
}
| HTTP | 含义 | 原因示例 |
|---|---|---|
400 | Bad Request | 缺少必填参数·非法值·非法JSON·SSRF目标URL |
401 | Unauthorized | API密钥无效·过期·格式不正 |
403 | Forbidden | 角色违规(如求职者调用企业专用工具) |
404 | Not Found | 指定资源不存在或无编辑权限 |
405 | Method Not Allowed | 以GET访问(仅接受POST) |
429 | Too Many Requests | 速率超限·暴力破解锁定中(参见 Retry-After) |
500 | Server Error | 内部错误(详情仅在 error_log) |